继承和多态(下)

继承和多态

目录:


承接上回

1.9proteced关键字🛰

在这里插入图片描述

1.10继承方式🛰

  • 单继承
class A{
    
}
class B extends A{
    
}

  • 多层继承
class A{

}
class B extends A{

}
class C extends B{
    
}
  • 不同类继承同一个类
class A{

}
class B extends A{

}
class C extends A{

}

1.11final关键字🛰

  • final int Size = 10 //常量;

  • final class B extend A {}//密封类:表示此类不能再被继承

  • final修饰方法//密封方法:代表此方法不能被重写

1.12继承与组合🛰

  • 继承是is - a的关系

    • 比如说狗是动物
  • 组合是has a or a part of

    • 比如说学校由学生和老师组成

    • class Student{
      
      }
      class Teacher{
      
      }
      class School{
          private Student[] students;
          private Teacher[] teachers;
      }
      

2.多态😋

2.1多态的概念🛰

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。

2.2多态的条件🛰

  1. 完成向上转型

    • 直接赋值

               Animal animal = new Bird("鹦鹉",2);
      
    • 方法的传参

           public static void func1(Animal animal){
       
           }
           public static void main(String[] args) {
               Bird bird = new Bird("鹦鹉",2);
               func1(bird);
           }
      
    • 方法的返回值

           public static Animal func2(){
               return new Bird("鹦鹉",2);
           }
      
  2. 完成方法的重写

  3. 通过父类的引用来调用这个重写的方法(动态绑定)
    在这里插入图片描述

2.3重写🛰

  • 满足方法重写的条件

    • 方法名相同
    • 方法的参数列表相同【个数,类型,顺序】
    • 方法的返回值相同
      • 协变类型:子类的返回值与父类的返回值是父子关系也可以
    • static修饰的方法不能被重写
    • private修饰的方法不能被重写
    • 子类的访问修饰符要大于等于父类的访问修饰符
  • 重写与重载的区别

    类型重载重写
    参数列表必须修改一定不能修改
    返回值类型可以修改一定不能修改
    访问限定修饰符可以修改一定不能做更严格的限制
  • 动态绑定

  • 	class Animal{
        private String name;
        private int age;
    
        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
            //eat();->也可以发生所谓的动态绑定,以后不要这样写代码
        }
    }
    class Bird extends Animal{
    
        public String wing;
        public Bird(String name, int age) {
            super(name, age);
        }
    
        public void fly(){
            System.out.println(getName()+" 正在飞");
        }
    
        @Override
        public void eat() {
            System.out.println(getName()+" 要吃鸟粮");
        }
    }
    	public static void main(String[] args) {
    //        Bird bird = new Bird("小鸟",3);
    //        Animal animal = bird;
            //父类的引用  引用了子类的对象
            Animal animal = new Bird("鹦鹉",2);
            animal.eat();//动态绑定 会输出子类的eat
    //        animal.fly();//不可以调用了  此时通过父类引用,只能调用自己特有的方法,不可以调用子类方法
    //        animal.wing;
        }
    
  • 静态绑定:例如方法的重载

2.4向上转型和向下转型🛰

2.4.1向上转型

在多态的条件中已经介绍

在这里插入图片描述

2.4.2向下转型

**向下转型非常不安全,不用 **

    public static void main(String[] args) {
        Animal animal = new Dog("狗子",3);
        if(animal instanceof Bird){
            //不是所有的动物都是鸟
            Bird bird = (Bird)animal;
            bird.fly();
        }
    }
    public static void main5(String[] args) {
        Animal animal = new Bird("鸟儿",3);
        Bird bird = (Bird)animal;//向下转型
        bird.fly();
    }

2.5多态的优缺点🛰

【使用多态的好处】
  1. 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
  2. 可扩展能力更强
  • 如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.
    public static void drawMap3(){
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        Shape[] shapes = {cycle, rect, cycle, rect, flower};
        for (Shape shape:shapes) {
            shape.draw();
        }
    }
    public static void drawMap2(){
         Rect rect = new Rect();
         Cycle cycle = new Cycle();
         Flower flower = new Flower();
         String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
         for (String shape : shapes) {
             if (shape.equals("cycle")) {
                 cycle.draw();
             } else if (shape.equals("rect")) {
                 rect.draw();
             } else if (shape.equals("flower")) {
                 flower.draw();
             }
         }
    }

    public static void main(String[] args) {
        drawMap3();
    }
【多态的缺陷】

代码的运行效率降低。

2.6尽量避免在构造方法中重写🛰

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        //eat();->也可以发生所谓的动态绑定,以后不要这样写代码
    }
    class Bird extends Animal{

    public String wing;
    public Bird(String name, int age) {
        super(name, age);
    }

    public void fly(){
        System.out.println(getName()+" 正在飞");
    }

    @Override
    public void eat() {
        System.out.println(getName()+" 要吃鸟粮");
    }
}
	public class Test {

    public static void main(String[] args) {
        Animal animal = new Animal("动物",10);
//        Animal animal = new Dog("狗子",3);
        animal.eat();
    }
}

结论: “用尽量简单的方式使对象进入可工作状态”, 尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触发动态绑定, 但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值