Java学习笔记(十二)面向对象---内部类

2020-02-17 16:08:27来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Java学习笔记(十二)面向对象---内部类

内部类的访问规则

  • 内部类可以直接访问外部类中的成员,包括私有成员。
    因为内部类中持有了一个外部类的引用,格式为:外部类名.this
  • 外部类要访问内部类,必须要建立内部对象。
class Outer {           //外部类
    private int x = 1;
    class Inner{        //内部类
        int x = 2;
        void function() {
            int x = 3;
            System.out.println(x);
            System.out.println(this.x);
            System.out.println(Outer.this.x);
        }
    }
    void method() {
        Inner in = new Inner();
        in.function();
    }
}
public class InnerClassDemo {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.method();
        Outer.Inner in = new Outer().new Inner();
        in.function();
    }
}

运行结果:

3
2
1
3
2
1

访问

  1. 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。
    格式: 外部类名.内部类名 变量名 = 外部类对象.内部类对象;
  2. 当内部类在成员位置上,就可以被成员修饰符所修饰。
    例如:private,将内部类在外部类中进行封装。
    static:使得内部类具有static的特性。(当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问的局限。)

静态内部类

  • 在外部其他类中,如何直接访问静态内部类的非静态成员
class Outer {
    private static int x = 1;
    static class Inner {
        void function() {
            System.out.println(x);
        }
    }
}
public class InnerDemo2 {
    public static void main(String[] args) {
        new Outer.Inner().function();
    }
}
  • 在外部其他类中,如何直接访问静态内部类的静态成员
class Outer {
    private static int x = 1;
    static class Inner {
        static void function() {
            System.out.println(x);
        }
    }
}
public class InnerDemo3 {
    public static void main(String[] args) {
        Outer.Inner.function();
    }
}
  • 当内部类中定义了静态成员,该内部类必须也是静态的
    以下代码编译会导致编译错误
class Outer {
    private static int x = 1;
    class Inner {               //此内部类中定义了静态成员但是此内部类不为静态
        static void function() {
            System.out.println(x);
        }
    }
}
public class InnerDemo3 {
    public static void main(String[] args) {
        Outer.Inner.function();
    }
}
  • 当外部类中的静态方法访问内部类时,内部类也必须是静态的。

内部类的定义原则

当描述一个事物时,这个事物的内部有事物,此时这个内部的事物需要使用内部类来描述。

局部内部类

  • 内部类定义在局部时:
  1. 不可以被成员修饰符修饰。
  2. 可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部变量,只能访问被final修饰的局部变量。(目前版本的jdk中,final可以省略)
class Outer {
    void method(final int x) {
        class Inner {
            void function() {
                System.out.println(x);
            }
        }
        new Inner().function();
    }
}
public class InnerDemo4 {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.method(7);
        out.method(8);//因为局部变量在栈内存中,每次一调用入栈,使用结束出栈。所以虽然是被final修饰,但是仍然可以重复调用。
    }
}

运行结果:

7
8

匿名内部类

  1. 匿名内部类其实是内部类的简写格式。
  2. 定义匿名内部类的前提:
    内部类必须是继承一个类或者实现接口。
  3. 匿名内部类的格式:new 父类或者接口(){定义子类的内容}
abstract class Abs {
    abstract void method();
}
class Outer {
    int x = 3;
    /*class Inner extends Abs {
        @Override
        void mthod() {
            System.out.println(x);
        }
    }*/
    public void function() {
        //new Inner().mthod();
        new Abs() {
            @Override
            void method() {
                System.out.println(x);
            }
        }.method();
    }
}
public class InnerDemo5 {
    public static void main(String[] args) {
        new Outer().function();
    }
}

运行结果

3

以上代码将注释部分,用匿名内部类的形式体现了出来。

  1. 匿名内部类是一个匿名子类对象。可以理解为带内容的对象。
  2. 匿名内部类中定义的方法最好不要超过3个。
  3. 如果一个类既没有实现接口也没有继承父类,可以使用Object类来创建匿名内部类。
    例如:
public class InnerClassTest {
    public static void main(String[] args) {
        new Object() {  //如果左边有Object类型引用(Object ob = ),将无法调用method方法
            public void method() {
                System.out.println("method run");
            }
        }.method();
    }
}

练习

interface Inter {
    void method();
}
class Test {
    //补足代码,通过匿名内部类
}
public class InnerClassTest {
    public static void main(String[] args) {
        Test.function().method();
    }
}

分析 Test.function().method(); 这行代码可以发现function()应该是Test类中一个静态方法,function()方法后面还有一个method()的调用,说明调用function()方法应是返回了一个对象而且是Inner类型的对象,从而才能继续调用method()方法。
可以得到以下代码:

interface Inter {
    void method();
}
class Test {
    //补足代码,通过匿名内部类
    static Inter function() {    //这里返回值类型为Inner
        return new Inter(){
           @Override
           public void method() {
               System.out.println("Hello World");
           }
       };
    }
}
public class InnerClassTest {
    public static void main(String[] args) {
        Test.function().method();
    }
} 

原文链接:https://www.cnblogs.com/liyuxin2/p/12324375.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Kafka系列3:深入理解Kafka消费者

下一篇:linux常用命令