美文网首页
OnJava8笔记5 -- 内部类

OnJava8笔记5 -- 内部类

作者: 给点阳光我就灿烂_ab56 | 来源:发表于2020-04-19 19:56 被阅读0次

内部类

一个定义在另一个类中的类,叫作内部类。

创建内部类

public class Parcel {
    class Contents {
        private int i = 11;

        public int value() { return i; }
    }
}
  • 在Parcel之外的类中想要创建Contents对象,需要 Parcel.Contents ( OuterClassName.InnerClassName )

  • 内部类自动拥有对其外围类所有成员和方法的访问权,即使是 private 的也可以。这是因为当内部类对象被创建时,一个外部类对象的引用被传递给这个内部类对象了。

  • 普通内部类不能有 static 字段和方法

内部类中的 .this 和 .new

.this

  • 在内部类中, *OuterClassName.this *(DotThis.this) 代表的是外部类对象的引用,单纯的 this 就是内部类对象的引用

.new

  • 外部类对象.new 用于创建内部类对象

    public class DotNew {
        public class Inner {}
        public static void main(String[] args) {
            DotNew dn = new DotNew();
            DotNew.Inner dni = dn.new Inner();
        }
    }
    

方法和作用域中的内部类

public class Parcel6 {
    private void internalTracking(boolean b) {
        if(b) {
            class TrackingSlip {
                private String id;
                TrackingSlip(String s) {
                    id = s;
                }
                String getSlip() { return id; }
            }
            TrackingSlip ts = new TrackingSlip("slip");
            String s = ts.getSlip();
        }
        // Can't use it here! Out of scope:
        //- TrackingSlip ts = new TrackingSlip("x");
    }
}

内部类只能在自己的作用域中能被使用

  • 方法和作用域中的内部类使用的外部变量必须是final的

匿名内部类

public interface Contents {
    int value();
}
public class Parcel7 {
    public Contents contents() {
        return new Contents() { // Insert class definition
            private int i = 11;

            @Override
            public int value() { return i; }
        }; // Semicolon required
    }

    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        Contents c = p.contents();
    }
}

在创建 Contents 对象代码之后插入一个类的声明,这个插入的类就是匿名类(没有具体名字)

  • 这里可以看成创建了一个继承自 Contents 的匿名类对象,然后通过前面的 new 表达式将匿名类对象向上转型成 Contents 对象
  • 匿名内部类中使用的外部变量必须是final 的
  • 匿名内部类,因为是匿名的,不能显式声明构造函数

匿名内部类中的参数初始化

public class Parcel9 {
    // Argument must be final or "effectively final"
    // to use within the anonymous inner class:
    public Destination destination(final String dest) {
        return new Destination() {
            private String label = dest;
            @Override
            public String readLabel() { return label; }
        };
    }
    public static void main(String[] args) {
        Parcel9 p = new Parcel9();
        Destination d = p.destination("Tasmania");
    }
}

可以看到第6行用到的外部变量是final的(jdk8之后不用明确写final了,但还是不能被改变)
为什么必须是final的? 参考知乎 胖君 的回答:https://www.zhihu.com/question/21395848

嵌套类

static类型的内部类叫做嵌套类。嵌套类对象没有指向外部创建他的类的对象引用

  • 要创建嵌套类对象,不需要外部类对象
  • 不能从嵌套类的对象中访问非静态外部类的对象
  • 嵌套类可以包含 static 字段和方法
  • 接口中的内部类自动是 public 和 static 的

为什么要使用内部类

  • 最重要的原因是可以间接实现类的多继承

    我们知道java中的类只能单继承,内部类可以间接实现多继承:

    public class Demo1 {
          public String name() {
              return "BWH_Steven";
          }
      }
      
      public class Demo2 {
          public String email() {
              return "xxx.@163.com";
          }
      }
      
      public class MyDemo {
      
          private class test1 extends Demo1 {
              public String name() {
                  return super.name();
              }
          }
      
          private class test2 extends Demo2  {
              public String email() {
                  return super.email();
              }
          }
      
          public String name() {
              return new test1().name();
          }
      
          public String email() {
              return new test2().email();
          }
      
          public static void main(String args[]) {
              MyDemo md = new MyDemo();
              System.out.println("我的姓名:" + md.name());
              System.out.println("我的邮箱:" + md.email());
          }
    }
    

    在MyDemo类中书写了两个内部类,test1和test2 两者分别继承了Demo1和Demo2类,这样MyDemo中就间接的实现了多继承

  • 使用匿名内部类实现回调功能(jdk8之后可以使用lambda表达式)
    当有这么个需求,一个方法的参数是接口对象,因为接口不能生成对象,而单独写一个类来实现接口又太浪费(因为这个方法可能只会被使用一次),这时匿名内部类很容易实现这一需求

    interface Demo {
        void interfaceMethod();
    }
    
    public class NiMingInnerClass {
    
        public void test(Demo demo) {
            demo.interfaceMethod();
        }
    
        public static void main(String[] args) {
            NiMingInnerClass innerClass = new NiMingInnerClass();
            innerClass.test(new Demo() {
                @Override
                public void interfaceMethod() {
                    System.out.println("接口方法被调用了");
                }
            });
        }
    }
    
  • 父类和接口中存在同名方法,而直接Override这个方法会导致只能保留一个方法,想要既保留继承自父类的实现,又保留接口中的方法,这时选择内部类很容易达到需求

    interface Demo2 {
        void test();
    }
    abstract class  SupClass {
        public void test() {
            System.out.println("SupClass test()");
        }
    
    }
    
    public class SameNameMethod extends SupClass {
        @Override
        public void test() {
            super.test();
            System.out.println("SameNameMethod test()");
        }
    
        private class InnerClass implements Demo2{
            @Override
            public void test() {
                System.out.println("Demo2 test()");
            }
    
    
        }
    
        public InnerClass getInner() {
            return new InnerClass();
        }
        public static void main(String[] args) {
            SameNameMethod test = new SameNameMethod();
            test.test();
            test.getInner().test();
        }
    }
    

相关文章

  • OnJava8笔记5 -- 内部类

    内部类 一个定义在另一个类中的类,叫作内部类。 创建内部类 在Parcel之外的类中想要创建Contents对象,...

  • 内部类

    成员内部类 局部内部类(定义在方法内和定义在作用域内的类) 匿名内部类

  • Java 内部类

    内部类包括成员内部类、方法内部类、*静态内部类、匿名内部类*。 内部类的作用 由于内部类的实现和外部类没有关系,内...

  • Java学习——内部类

    内部类 一,成员内部类(包括静态内部类和非静态内部类) 非静态内部类可以直接访问外部类的成员,反之则不行 非静态内...

  • Java 内部类、静态内部类、方法内部类(未完待续)

    内部类 什么是内部类?内部类其实就是在一个类中创建的类。内部类有四种: 成员内部类 静态内部类 局部内部类 匿名内...

  • java 内部类

    一般有四种内部类的使用方式: 嵌套的内部类 方法内的内部类 静态内部类 匿名内部类 什么时候用内部类: 有时候明显...

  • 内部类

    内部类 1.可以访问访问其外部类所有属性和方法,无需创建外部类对象 2.必须创建内部类对象,否则无法从外部类访问内...

  • ?2020-07-23(7月28号再来完善:内部类)

    1,成员内部类; 2,静态内部类; 3,局部内部类; 4,匿名内部类; 5,复习代码块

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • java——内部类

    内部类 定义: 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内...

网友评论

      本文标题:OnJava8笔记5 -- 内部类

      本文链接:https://www.haomeiwen.com/subject/spnbbhtx.html