【 final、权限、内部类 】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sugar_i/article/details/81280155

final关键字:

代表最终不可变的。

用法:
1、用来修饰一个类:不能有子类,所以其中所有的方法都不嗯呢该被覆盖重写。
2、用来修饰一个方法:方法不能被覆盖重写。
3、用来修饰一个局部变量(Variable):一次赋值,终生不变。
4、用来修饰一个成员变量:一次赋值,终生不变。没有默认值需要手动赋值。

final修饰的类又叫“太监类”。
final关键字abstract关键字冲突,不能同时是使用。
格式:

public final class 类名{
    //类内容   
}

final用来修饰一个局部变量,那这个局部变量,一次赋值终生不变。

final int numb = 15;
System.out。println(numb);// 15

注意:
final修饰引用类型的数据,地址值不可变,但是通过地址修改内部的内容是可以的。
final修饰基本类型,一次赋值,终生不变。
final用来修饰一个成员变量,也是一次赋值,终生不变。

成员变量本来是默认值的。一旦final修饰了成员变量,那么将不再具有默认值。
成员变量赋值:
1、直接定义的时候赋值。
2、通过构造方法赋值。

final int numB = 15;
System.out.println(numB); // 15

//  numB = 20; // 错误写法!
//  numB = 15; // 错误写法!

final int numC;
numC = 25; // 分成两步,是正确写法!
System.out.println(numC); // 25
System.out.println("==============");

final int[] array = {10, 20, 30}; // 地址值不可变
System.out.println(Arrays.toString(array)); // [10, 20, 30]
array[1] = 25;
System.out.println(Arrays.toString(array)); // [10, 25, 30]

权限修饰符

                   public > protected > (default) > private
同一个类(自己)        YES     YES         YES          YES
同一个包(邻居)        YES     YES         YES          NO
不同包子类(儿子)      YES      YES         NO          NO
不同包非子类(陌生人)   YES      NO          NO          NO

注意事项:
1. (default)并不是关键字default,而是什么都不写。
2、只要不是相同的包都需要导包。

内部类

概念:在一类的里面再定义一个类,里面的类就叫做内部类。

内部类的分类:
1、成员内部类
2、局部内部类(包含匿名内部类)

成员内部类的定义格式:

修饰符 class 类名称{
    修饰类 class 内部类名称{
        //...
    }
}

使用 :
1、间接使用:在外部类的成员方法中,创建一个内部类的对象。直观调用外部类对象的外部成员方法即可。
2、直接使用:直接使用内部类对象,公示:

// 外部类.内部类 对象名 = new 外部类().new 内部类();
Outer.Inner obj = new Outer().new Inner();
obj.methodInner();

备注 :
1、外部类和内部类仍然可以继续定义成员变量、成员方法、而且用本类当中的东西,仍然是随便用。
2、内部类如果访问外部类的内容,可以随意。
3、外部类访问内部类的内容,必须有一个内部类的对象才行。
4、编译生成的.class文件名称为“外部类$内部类.class

内部类访问外部类的成员变量:

外部类名.this.成员变量名;

成员内部类:定义在外部类内,在方法外
局部内部类:外部类的成员方法内,只有本方法内才有用。(一定要定义局部内部类,然后才能使用。)

成员内部类的权限修饰符:
1、外部类:public、(default
2、成员内部类:publicprotected、(default)、privete
3、局部内部类:什么都不能写,而且这并不是(default)方法。

局部内部类访问所在的方法的局部变量,那么这个变量一定需要是有效的final才行。
因为局部变量和内部累创建的对象生命周期不同。

匿名内部类

接口名称 对象名 = new 接口名称(){
    //实现所有抽象方法。
};

解析:
new:创建对象
右侧的接口名称:匿名内部类所实现的接口名。
右侧的{ }:匿名内部类。

public class DemoMain {

   public static void main(String[] args) {
       // 有对象名叫obj,也有类名称叫MyInterfaceImpl
       MyInterface obj = new MyInterfaceImpl();
       obj.method();

       // 没有对象名称,匿名对象,但是有类名称Impl
       new MyInterfaceImpl().method(); // 匿名对象

//        MyInterface inter = new MyInterface(); // 错误写法!

       // 匿名内部类,没有类名称;但是有对象名称叫做obj2
       MyInterface obj2 = new MyInterface() {
           @Override
           public void method() {
               System.out.println("匿名内部类执行!");
           }
       };

       obj2.method();

       // 既是匿名对象,也是匿名内部类
       new MyInterface() { 
           @Override
           public void method() {
               System.out.println("匿名对象+匿名内部类");
           }
       }.method();
   }

}

匿名对象类的好处:省去了单独定义一个实现类的麻烦。

Anonymous匿名内部类

1、匿名内部类的使用前提:必须有继承或者接口实现关系。
2、匿名内部类可以使用接口,也可以使用抽象类,也可以使用普通的类。只要不是final的,就可以。
3、匿名内部类(局部内部类)编译之后因为没有名字,所以产生的字节码文件是“外部类名称$1.class”。

接口作为成员变量的类型。
接口作为方法的返回值。

public class Body { // 外部类,代表身体

   private int num = 10;

   public void methodOuter() {
       Heart heart = new Heart();
       heart.beat();

//        System.out.println(age); // 错误
       System.out.println(heart.age); // 正确
   }

   public class Heart { // 内部类,代表心脏
       int age = 30;

       public void methodInner() {
           System.out.println(num);
       }

       public void beat() {
           System.out.println("蹦跶~蹦跶~蹦跶~");
       }
   }
}

测试类:

// 通过Body间接使用Heart
Body body = new Body(); // 创建了外部类对象
body.methodOuter();

// 直接使用Heart内部类对象
Body.Heart heart = new Body().new Heart();
heart.beat();
heart.methodInner(); // 10

猜你喜欢

转载自blog.csdn.net/Sugar_i/article/details/81280155