个人笔记 —— 多态,内部类

Day Eight

  • 昨日补充:常见的final类:
    String Math
    String不可变的: CharSequence - 字符序列 - 字符数组
    底层实现: 字符数组 —> 字节数组 byte[] value
    final value = 其他值
    String str = “hello”;
    str = “hi”;

多态

  • 接口作为方法参数, 接口作为返回值:
    具体使用的都是接口的实现类对象

  • 多态的前提:

      class MyInterfaceAImpl extends Object implmenets MyInterfaceA
      MyInterfaceA a = new MyInterfaceAImpl() -> 向上造型
      Object o = new MyInterfaceAImpl() -> 向上造型
      Fu fu = new Zi();
      Animal a = new Cat();
    

    父类型引用 指向 子类型对象 —> 向上造型

    父类型 a = new 子类型对象();
    接口类型 a = new 实现类对象();
    

    编译器 看 = 左边类型, 运行时JVM 看 = 右边类型

    左边类型决定了可以调用哪些变量和能够调用哪些方法,
    右边类型决定了最终使用的方法是哪个 - 优先调用自己重写过的
    变量为父类变量,方法为子类继承(即调用父类的方法)和重写的方法(子类自己新增的方法和成员变量无法被调用)

    口诀: 编译看左边, 运行看右边

    • 提前得知, 引用的 是什么类型的对象
      Animal —> abstract void eat()
      Cat —> void catchMouse() {}
      Dog —> void watchHouse() {}

      多态:

      Animal a1 = new Cat();
      Animal a2 = new Dog();
      
    • 未提前得知 引用的 是什么类型的对象(容易出现异常)
      ClassCastException: 类型转换异常

    • 解决方案:
      转换之前先判断引用 实际上是不是要转换的类型对象
      引用a instanceof 子类型 => 返回值类型:boolean
      判断 a 是不是子类型对象

内部类: 在类中写的类

例如:
人体类 中写了一个 心脏类
车类 中写了一个 发动机类

  • 种类:成员内部类,静态内部类,局部内部类 [ 匿名内部类 ]
    • 成员内部类: 访问权限修饰: public,protected,(default),private
      语法:

       public class Outer{
        // ...
        	public class Inner{
        //....
        	}
       }
      
      • 使用:
        内部类中:可以随意使用外部类成员,包括私有成员
        外部类中:使用内部类成员时需要创建内部类的对象
        创建内部类对象格式:

        外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
        

        无关类中: 使用内部类成员

      1. 间接调用,在外部类方法中调用内部类方法
        main方法中,调用外部类方法

      2. 直接调用,需要创建内部类对象
        外部类.内部类 a = new 外部类().new 内部类();
        内部类和外部类有同名成员变量
        外部类的成员变量: 外部类.this.变量
        内部类的成员变量: this.变量

         class Car { //外部类
          class Engine { //内部类					 
          }
         }					
        

        定义类:

         public class Person {
         	private boolean live = true;
          	class Heart {
          		public void jump() {
          		// 直接访问外部类成员
          		if (live) {
          			System.out.println("⼼脏在跳动");
          		} else {
          			System.out.println("⼼脏不跳了"); }
          		}
          	}
          	public boolean isLive() {
          		return live;
          	}
           	public void setLive(boolean live) {
            		this.live = live;
           	}
         }
        

        测试类:

         public class InnerDemo {
         	public static void main(String[] args) {
          		// 创建外部类对象
          		Person p = new Person(); // 创建内部类对象
          		Heart heart = p.new Heart();
          		// 调⽤内部类⽅法
          		heart.jump();
          		// 调⽤外部类⽅法
          		p.setLive(false);
          		// 调⽤内部类⽅法
          		heart.jump();
          	} 
          }
          
         输出结果:
         ⼼脏在跳动
         ⼼脏不跳了
        
    • 局部内部类:
      在方法内部定义类, 只在方法中有效
      在局部内部类中, 使用局部变量, 必须是final修饰的
      JDK8 后,局部变量事实上没有发生改变,那么final可以省略

      特点:
      一次性的类, 只能用一次
      不能使用权限修饰符

      局部内部类, 需要类只使用一次,优化后 —> 匿名内部类

    • 匿名内部类: 继承抽象类或实现接口
      语法:

       new 接口/抽象类() {
       	int a;
       	...		// 实现的所有抽象方法
       }
      

      匿名内部类只能用一次new一个对象
      匿名对象,只能使用一次,只能调用一次方法
      注意: 匿名内部类 和 匿名对象 不是一回事 ! ! !

    • 静态内部类 对比于 成员内部类 => 静态方法 对比于 成员方法
      前两者两种类型之间的区别和后两者方法之间的区别相似,可以推断出来。(例如:静态内部类中不能调用成员变量,就像静态方法中不能调用成员方法。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值