第十章 花里胡哨的内部类

不得不说,编程思想真本书的信息量是真的大,有相当多的东西,非常的细节,必须要自己总结之后才会发现收获。

一定要注意书中外部类和外围类的区别。

class AA {
    class BB {}
}

class CC {}

AA类与CC类都是外部类,但是只有AA叫外围类。

一、类中的内部类

首先很重要的一点,在类中定义的内部类,是可以在外部类中创建其对象的。但是,在方法和作用域中定义的内部类,一旦出了方法和作用域的范围,这个内部类便不可以在被访问了。

1.在外部类的静态方法中,是一定要指明对象的类型的OuterClass.InnerClass。(看懂没有关系,看列子)

2.要创建内部类对象必须要,要有其外围类对象的引用。(嵌套类可以不必需要)

3.内部类可以访问外围类的所有成员(内部类是可以直接使用外围类成员的)(千万注意不是内部类对象可以访问外围类对象的所用成员,书上说的有不准确的地方),外围类也可以访问内部类的所有成员只不过形式不同。

实例:

class AA {
    private void printA1() { System.out.println("printA1()"); } 
    public void printA() { System.out.println("printA()"); }
    
    class BB { 
        public void printB() { 
            printA1();//证明内部类可以访问外部类的所有成员,而且是直接访问
            System.out.println("BB"); 
        }
    }
    
    public BB getBBClass() {
        return new BB();
    }
}

public class InneratClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AA a = new AA();
        AA.BB b = a.getBBClass();
        b.printB();
        //b.printA();如果这样写就会报错
    }

}

结果:

 

外围类访问内部类私有成员:

class Outer {
    class Inner {
        private Inner(int i) {}
        private void print() {
            System.out.println("Inner");
        }
    }
    
    Inner getInner() {
        Inner i = new Inner(1);
        //外围类访问内部类私有成员
        i.print();
        return i;
    }
}

public class CreateInner {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer o = new Outer();
        Outer.Inner i = o.getInner();
        
    }

}

 

 4、“.this”返回外围类对象的引用

用法实例:

public class This {
    class A {
        This getOuterClass() {
            return This.this;
        }
    }
    A getAClass() {
        return new A();
    }
    void print() {
        System.out.println("This");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        This t = new This();
        This.A a = t.getAClass();
        This b = a.getOuterClass();
        b.print();
        
    }

}

5.“.new”创建内部类对象的另外一种方式

方式一:外围类用一个方法返回内部类引用

class Outer {
    class Inner {
        void print() {
            System.out.println("Inner");
        }
    }
    //创建内部类的第一种方式,在外围类用一个方法返回内部类引用
    Inner getInner() {
        return new Inner();
    }
}

public class CreateInner {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer o = new Outer();
        Outer.Inner i = o.getInner();
        i.print();
    }

方式二:.new方式

class Outer {
    class Inner {
        void print() {
            System.out.println("Inner");
        }
    }
    
}

public class CreateInner {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer o = new Outer();
        Outer.Inner i = o.new Inner();
        i.print();
    }

}

6.向上转型

interface Fruit {
    void eat();
}

class Outer1  {
    private class Apple implements Fruit{
        public void eat() {
            System.out.println("Apples are good!");
        }
    }
    
    Fruit getApple() {
        return new Apple();
    }
}
public class InnerUpcast {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer1 o = new Outer1();
        Fruit f = o.getApple();
        f.eat();
        
    }

}

7、继承会把内部类一起继承,内部类就是外围类的一部分,就是它的成员,这一点书里没有说到。

class Fruit1 {
     class Apple {
        public void eat() {
            System.out.println("Apples are good!");
        }
    }
}

public class StaticInnerClass extends Fruit1{
    
    public static void main(String[] args) {
        Fruit1 f = new Fruit1();
        StaticInnerClass s = new StaticInnerClass();
        StaticInnerClass.Apple a1 = f.new Apple();
        StaticInnerClass.Apple a2 = s.new Apple();
        a1.eat();
        a2.eat();
    }
}

输出:

Apples are good!
Apples are good!

 

二、方法和作用域中的内部类

类中的内部类是类的一部分;方法和作用域中的内部类也是其一部分,离开了方法和作用域其内部类便不可访问。

方法和作用域中的内部类,与类中的内部类一样需要外围类对象引用。

实例:

public class MethodInner {
    
    interface Fruit {
        void eat();
    }
    
    Fruit getApple() {
        class Apple implements Fruit{
            public void eat() {
                System.out.println("Apples are good");
            }
        }
        return new Apple();
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MethodInner m = new MethodInner();
        Fruit f = m.getApple();
        f.eat();
    }

}

三、匿名内部类

匿名内部类一般都是作为临时使用的。

1.匿名内部类如果使用在其外部定义的数据,那么要求这个数据是final的,否则编译器会给出错误。《编程思想》是这么说的,但是经我验证并不会报错。可能是java版本更新换代的原因吧,有出入是很正常的

实例:

public class AnonymityInner {

    class Fruit {
        String s;
        Fruit(final String s) {
            this.s = s;
        }
        void eat() {
            System.out.println("Fruit is " + s);
        }
    }
    Fruit getApple(String i) {
        return new Fruit("good") {
            void eat() {
                String s = i;
                System.out.println(s + " Apples");
            }
        };
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s = "5";
        AnonymityInner a = new AnonymityInner();
        Fruit f = a.getApple(s);
        f.eat();
    }

}

 

四、嵌套类

1.静态内部类(即嵌套类)中可以定义static成员,而普通的内部类是不准有static成员的。

2.静态内部类不需要外围类的引用来创建对象,它也就失去了外围类引用带来的好处,嵌套类只能够访问外围类的静态成员,类似于静态方法。

使用起来就像是使用类的静态域一样

class Fruit1 {
    static class Apple {
        public void eat() {
            System.out.println("Apples are good!");
        }
    }
}
public class StaticInnerClass {
    
    public static void main(String[] args) {
        
        Fruit1.Apple a = new Fruit1.Apple();
        a.eat();
    }
}

接口中的嵌套类:

package innerclass;

interface Fruit1 {
    //接口中的类自动为嵌套类,且是public
     class Apple {
        public void eat() {
            System.out.println("Apples are good!");
        }
    }
}

public class StaticInnerClass implements Fruit1{
    
    public static void main(String[] args) {
        StaticInnerClass.Apple a2 =new StaticInnerClass.Apple();
        a2.eat();
    }
}

输出:

Apples are good!

 

内部类的写法真的是五花八门ε=(´ο`*)))唉

posted @ 2019-08-22 15:34  卑微芒果  Views(133)  Comments(0Edit  收藏  举报