JAVA_SE第十一章 内部类

一、内部类:在类中定义类

(一)成员内部类:实例内部类+静态内部类
(二)局部内部类
(三)匿名内部类

(一)成员内部类

成员内部类基本知识点

成员内部类指的是类作为另一个类的一个成员。

A.实例内部类

(1)创建内部类格式

1) 先创建外部类对象;然后再在外部类对象基础上,调用内部类的所有操作,包括创建内部类。
Outer O = new Outer(); 
Outer.Inner i = O. new Inner();
2) 如果只创建内部类对象,外部类可以匿名,所以不用创建外部类对象,直接用匿名外部类对象new Outer()来代替。
Outer.Inner oi = new Outer().Inner();

(2)内部类成员与其他成员的访问关系:

1)内部类可以直接访问外部类的成员,包括私有,因为他们都属于外部类;
2)外部类要访问内部类的成员,必须创建对象,因为对于外部类的其他成员来说,内部类是一个并列的单独的类;

B、成员内部类私有使用

私有化后,像其他私有成员变量一样,私有内部类别的类也不能直接访问。
如果像像访问私有内部类里的方法,需在外部类内创建public方法,在public方法内创建对象,再在里面调用私有内部类的方法。
跟对私有属性创建专门的访问器是一样的。

C、成员内部类静态化后

(1)静态内部类内如果有静态成员方法 ,则沿用以前,一路直接点调用到底。
(2)静态内部类内如果有普通成员方法
调用方法:Outer.Inner oi = Outer.new Inner();;//即用类名访问 ,new 可提到前面,写为new Outer .Inner();

看作静态成员

D、变量同名时的调用方法。

//要求按顺序输出30,20,10;
class Outer{
    public int num = 10 ;
    class Inner {
        public num = 20;
        public void show(){
            int num = 30;
            System.out.println(num); //30
            System.out.println(this.num); //20
            System.out.println(Outer.this.num); //10
        }
    }
}

(二)局部内部类

(1)局部内部类基本知识:

类作为局部变量,即在方法中定义了一个类(用的少),只能在方法内创建对象使用,意义不大。
class Outer2 {
    public void method(){
        class Inner{
            public void print(){
                System.out.println("Hello World!");
            }
        }
        Inner i = new Inner();
        i.print();
    }
}

(2)与其他成员的访问关系

访问同方法内的其他成员时,只能访问final格式常量。
局部内部类在访问他所在方法中的局部变量时必须使用final修饰?为什么
因为当调用这个方法时,局部变量如果没有用final修饰,他的声明周期和方法的声明周期是一样的,当方法弹栈,这个局部变量也会消失,但是如果局部内部类对象还没有被回收,这个时候使用这个变量就会消失,所以可能访问不到。如果用final修饰后,就会放入常量池,即使方法弹栈,常量孩子,就可以继续访问。

(三)匿名内部类(常用)

(1)匿名内部类介绍

匿名内部类其实是内部类的简化写法。用于对接口的实现或对父类的继承时只用一次,不用创建对象。好处是不用单独创建类重写方法,而是直接在创建匿名类的时候书写方法。本质上是一个没有名字的子类对象。
interface Inter {
    public void print();
}
class outer {
    public void method (){
        new Inter(){    public void print(){
            System.out.println("print");
        }}.print(); //子类对象调用自己的方法。
    }
}
public class NoNameInnerClass {
    public static void main(String[] args) {
        outer O = new outer();
        O.method();
    }
}

(2)匿名内部类注意:

在接口或父类中只有一个方法中用时好用,有两个以上的方法需要调用时,就应该创建有名子类:

interface Inter {
    public void print1();
    public void print2();
}
class outer {
    public void method (){
        new Inter(){
            public void print1(){
            System.out.println("print1");
            }
            public void print2(){
            System.out.println("print2");
            }           
         }.print1(); 
         new Inter(){
            public void print1(){
            System.out.println("print1");
            }
            public void print2(){
            System.out.println("print2");
            }   
         }.print2(); 
    }
}

或者稍微改进一点:

interface Inter {
    public void print1();
    public void print2();
}
class outer {
    public void method (){
        Inter 1 = new Inter(){
            public void print1(){
            System.out.println("print1");
            }
            public void print2(){
            System.out.println("print2");
            }
        /*甚至当子类需要有自己的新方法时就不能用了*/
         }; 
        i.print1();     
        i.print2(); 
    }
}

二、 函数式接口

只包含一个抽象方法的接口(其他方法的数量不考虑)

Lamda表达式 只能用于函数式接口

作用:替换匿名内部类的语法
()-> {};

class LaDemo{

    //方法二  匿名内部类的方式
/*  la a = new la(){
        public void func(){
            System.out.println("func");
        }
    };*/
    //方法三  Lambda无参数无返回值
//  la a1 = ()  ->  {System.out.println("func");};
//  la a2 = ()  ->  System.out.println("func");

    //无参数有返回值
    /*la a1 = () -> {return 11;};
    la a2 = () -> 11;*/

    //形参列表
//  la a1 = (m) -> {System.out.println(m);};

    //带参数带返回值
    //la a1 = (n)-> {return n;};
    //la a1 =n-> n;
}

猜你喜欢

转载自blog.csdn.net/gegeyanxin/article/details/80558754