Java封装

 一、Java面向对象的三大特征
    《1》封装:封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起
            来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据
            细节,只保留一些接口使其与外界发生联系。也就是说用户无需知道内部的数据和
            方法的具体实现细节,只需根据留在外部的接口进行操作就行。
    《2》继承:从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能
             扩展新的能力。
    《3》多态:方法的重写、重载与动态连接构成多态性。

二、封装
1、封装是指,一种将抽象性函式接口的实例细节部份包装、隐藏起来的方法。
     封装防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,
     必须通过严格的接口控制,通过该类提供的方法来实现对隐藏信息的操作和访问。
2、好处:
    《1》只能通过规定的方法访问数据。
    《2》隐藏类的实例细节,方便修改和实现。
3、实现类的封装的步骤:
     《1》修改属性的可见性,在属性的前面添加修饰符
     《2》对每个值属性提供对外的公共方法访问,如创建 getter/setter(取值和赋值) 方
             法,用于对私有属性的访问
     《3》在 getter/setter 方法里加入属性的控制语句,例如我们可以加一个判断语句,对
              于非法输入给予否定。
Java封装Java封装

三、包package
1、作用:
     (1)把功能相似或相关的类或借口组织在同一个包中,方便类的查找和使用
     (2)包采用了树形目录的存储方式
             同一个包中的类名字是不同的,不同的包中类的名字可以相同
             当调用两个不同包中相同类名的类时,应该加上包名加以区别。
      (3)包限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
2、定义:
package 包名 //注意:必须放在源程序的第一行,包名可用"."号隔开
3、使用import关键字,在不同包中使用另一个文件中的类。
     例如: import  packagename.类名 ;
               import 包名.*  //将包下所有的文件都导入进来,*是通配符
4、包的命名:全小写字母拼音

四、访问修饰符
Java封装Java封装
   不同的访问修饰符的访问范围。
   比如private修饰的属性或者方法,只能在当前类中访问或者使用。
   默认是什么修饰符都不加,默认在当前类中和同一包下都可以访问和使用。
   protected修饰的属性或者方法,对同一包内的类和所有子类可见。
   public修饰的属性或者方法,对所有类可见。

五、this关键字
1、this关键字代表当前对象。
     使用this.属性操作当前对象的属性,this.方法调用当前对象的方法。

六、内部类 
1、(1)内部类:类的定义在另一个类(外部类)的定义内部
     (2)内部类可以是静态static的,也可用public,default,protected和private修饰。
            (而外部顶级类即类名和文件名相同的只能使用public和default)
     (3)注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两
             类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成
             后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以    
             和外部类的相同。
2、作用:
     (1)内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中
             的其他类访问该类
     (2)内部类的方法可以直接访问外部类的所有数据,包括私有的数据
     (3)内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
     (4)内部类允许继承多个非接口类型

3、成员内部类 
//外部类People
public class People {
     private String name = "LiLei"; //外部类的私有属性
     //内部类Student
     public class Student {
          String ID = "20151234"; //内部类的成员属性
          //内部类的方法
          public void stuInfo(){
               System.out.println("访问外部类中的name:" + name);
               System.out.println("访问内部类中的ID:" + ID);
          }
     }

     //测试成员内部类
     public static void main(String[] args) {
          People a = new People(); //创建外部类对象,对象名为a
          Student b = a.new Student(); //使用外部类对象创建内部类对象,对象名为b
          // 或者为 People.Student b = a.new Student();
          b.stuInfo(); //调用内部对象的suInfo方法
     }
}
成员内部类的使用方法:
(1)Student类相当于People类的一个成员变量,所以Student类(成员内部类)可以使
         用任意访问修饰符
(2)Student类在People类里,所以访问范围在类里的所有方法均可以访问People的属
        性(即内部类里可以直接访问外部类的方法和属性,反之不行)
        成员内部类可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要       
        访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
(3)定义成员内部类后,必须使用外部类对象来创建内部类对象,
        即内部类 对象名=外部类对象.new 内部类()
(4)如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或
        方法,如果要访问外部类的成员变量,可以使用this关键字。例如:a.this
(5)成员内部类不能含有static的变量和方法,因为成员内部类需要先创建了外部类,才
        能创建它自己的。

4、静态内部类(嵌套类)
 //外部类People
public class People {
     private String name = "LiLei"; //外部类的私有属性
 
/*外部类的静态变量。
Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。 */

     static String ID = "510xxx199X0724XXXX";

     //静态内部类Student
     public static class Student {
          String ID = "20151234"; //内部类的成员属性
          //内部类的方法
          public void stuInfo(){
               System.out.println("访问外部类中的非静态变量name:" + (new People().name));     
               System.out.println("访问外部类中的静态变量ID:" +People.ID);
               System.out.println("访问内部类中的ID:" + ID);
          }
     }

     //测试成员内部类
     public static void main(String[] args) {
          Student b = new Student();      //直接创建内部类对象,对象名为b
           b.stuInfo();     //调用内部对象的suInfo方法
      }
}

结果:
访问外部类中的非静态变量name:LiLei
访问外部类中的静态变量ID:510xxx199X0724XXXX
访问内部类中的ID:20151234
静态内部类是static修饰的内部类。
静态内部类特点是:
(1)静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类().成员 的方式访问
(2)如果外部类的静态成员与内部类的成员名称相同,可以通过类名.静态成员 访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不同,则可通过成员名 直接调用外部类的静态成员。
(3)创建静态内部类的对象时,不需要外部类的对象,可以直接创建
         内部类 对象名=new 内部类()
(4) 嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也
         不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,    
          方便调用。

5、局部内部类:内部类定义在方法和作用域内
//外部类People
public class People {
     //定义在外部类中的方法内:
     public void peopleInfo() {
          final String sex = "man"; //外部类方法中的常量
          class Student {
               String ID = "20151234"; //内部类中的常量
               public void print() {
                    System.out.println("访问外部类的方法中的常量sex:" + sex);
                    System.out.println("访问内部类中的变量ID:" + ID);
               }
           }
    
          Student a = new Student(); //创建方法内部类的对象
          a.print();//调用内部类的方法
     }

     //定义在外部类中的作用域内
     public void peopleInfo2(boolean b) {
          if(b){
               final String sex = "man"; //外部类方法中的常量
               class Student {
                    String ID = "20151234"; //内部类中的常量
                    public void print() {
                         System.out.println("访问外部类的方法中的常量sex:" + sex);
                         System.out.println("访问内部类中的变量ID:" + ID);
                    }
               }
               Student a = new Student(); //创建方法内部类的对象
               a.print();//调用内部类的方法
          }
     }

     //测试方法内部类
     public static void main(String[] args) {
          People b = new People(); //创建外部类的对象
          System.out.println("定义在方法内:===========");
          b.peopleInfo(); //调用外部类的方法
          System.out.println("定义在作用域内:===========");
          b.peopleInfo2(true);
     }
}

输出结果:
定义在方法内:===========
访问外部类的方法中的常量sex:man
访问内部类中的变量ID:20151234
定义在作用域内:===========
访问外部类的方法中的常量sex:man
访问内部类中的变量ID:20151234
(1)局部内部类只在该方法或条件的作用域才能使用,退出这些作用域后无法引用。

6、匿名内部类
(1)匿名内部类:没有名字的内部类。
        匿名内部类只能使用一次,通常用来简化代码编写。
        使用匿名内部类的条件:必须继承一个父类或实现一个接口。
(2)
public class Outer {
     public Inner getInner(finalString name, String city) {
          returnnew Inner() {
               private String nameStr = name;
               public String getName() {
                    return nameStr;
               }
          };
     }

     public static void main(String[] args) {
          Outer outer = new Outer();
          Inner inner = outer.getInner("Inner", "NewYork");
          System.out.println(inner.getName());
     }
}

// 注释后,编译时提示类Inner找不到
interface Inner {
     String getName();
}
//new 匿名类,这个类是要先定义的,如果不先定义,编译时会报错该类找不到
(1)匿名内部类是不能加访问修饰符的。
        注意:new 匿名类,这个类是要先定义的,如果不先定义,编译时会报错该类找不到
(2)当所在的方法的形参需要在内部类里面使用时,该形参必须为final
        例如:形参name定义为final,而形参city没有被使用则不用定义为final。
        (简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,
          而导致内部类得到的值不一致,于是用final来让该引用不可改变)
(3)匿名内部类没有名字,是用默认的构造函数(无参构造函数)。如果需要该类有带参
        数的构造函数,示例如下:
public Inner getInner(final String name, String city) {
     return new Inner(name, city) {
          private String nameStr = name;
          public String getName() {
               return nameStr;
          }
     };
}
注意: 这里的形参city,由于它没有被匿名内部类直接使用,而是被抽象类Inner的构造函数所使用,所以不必定义为final。

参考链接: