初识继承与多态

本文探讨了编程中为何需要继承,通过实例解释了如何通过继承减少代码冗余。同时,详细阐述了Java中的继承概念,包括父类与子类的关系、继承的特性以及子类如何调用父类的字段和方法。接着,文章介绍了多态的概念,强调了多态必须基于继承和方法重写,并解释了“向上转型”的含义。最后,讨论了多态在实际编程中的应用及其带来的好处,如降低类调用者的使用成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承与多态

1.为什么会出现继承呢?
因为平时在写代码的时候会出现许多的相同的代码,这就出现了代码的冗余,这时候用继承就可以解决这个问题。

public class Animal {   
        public String name;      
        public Animal(String name) {  
          this.name = name;   
       }      
        public void eat(String food) {  
          System.out.println(this.name + "正在吃" + food);   
      } 
 } 
class Cat { 
       public String name;    
       public Cat(String name) {   
          this.name = name; 
      }     
      public void eat(String food) {   
        System.out.println(this.name + "正在吃" + food);   
     } 
 }
class Bird {
         public String name;   
         public Bird(String name) {      
            this.name = name;  
        }       
        public void eat(String food) {     
           System.out.println(this.name + "正在吃" + food);  
      }     
      public void fly()
       {     
       System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");  
       }                                 
  }     

这时候用继承就会减少你的代码量
这个代码我们发现其中存在了大量的冗余代码.
仔细分析, 我们发现 Animal 和 Cat 以及 Bird 这几个类中存在一定的关联关系:

1.这三个类都具备一个相同的 eat 方法, 而且行为是完全一样的.
2.这三个类都具备一个相同的 name 属性, 而且意义是完全一样的.
3.从逻辑上讲, Cat 和 Bird 都是一种 Animal (is - a 语义). 此时我们就可以让 Cat 和 Bird 分别继承 Animal 类, 来达到代码重用的效果.

此时, Animal 这样被继承的类, 我们称为 父类 , 基类 或 超类, 对于像 Cat 和 Bird 这样的类, 我们称为 子类, 派生类
和现实中的儿子继承父亲的财产类似, 子类也会继承父类的字段和方法, 以达到代码重用的效果

class Animal {  
    public String name; 
    public Animal(String name) {    
         this.name = name;  
    } 
    public void eat(String food) {      
       System.out.println(this.name + "正在吃" + food);   
     }
 } 
 
    class Cat extends Animal {   
    public Cat(String name) {      
     // 使用 super 调用父类的构造方法.        
       super(name);   
    } 
} 
 
class Bird extends Animal {  
   public Bird(String name) { 
        super(name); 
     } 
    public void fly() {       
      System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿"); 
    } 
} 
 
public class Test {  
       public static void main(String[] args) {   
       Cat cat = new Cat("小黑");    
       cat.eat("猫粮");     
       Bird bird = new Bird("圆圆");   
       bird.fly();    
     }
 } 

使用** extends **指定父类.
Java 中一个子类只能继承一个父类 (而C++/Python等语言支持多继承).
子类会继承父类的所有 public 的字段和方法. 对于父类的 private 的字段和方法, 子类中是无法访问的.
子类的实例中, 也包含着父类的实例. 可以使用 super 关键字得到父类实例的引用.
子类继承父类除了构造方法的所有属性和方法,子类要调用父类的构造方法,并且写在首部。

多态的认知
多态必须要有继承和方法的重写,还有父类引用子类对象
也就是向上转型
为啥叫 “向上转型”? 在面向对象程序设计中, 针对一些复杂的场景(很多类, 很复杂的继承关系), 程序猿会画一种 UML 图的方式来表 示类之间的关系. 此时父类通常画在子类的上方. 所以我们就称为 “向上转型” , 表示往父类的方向转.
运行时绑定————多态
在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引 用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定

下面是多态的关于向上转型的代码

class Animal{
    public String name;
    public int age;
    public Animal(){

    }
    public Animal(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("hhhhh");
    }
    public void eat(){
        System.out.println("吃吃");
    }
}
class Cat extends Animal{
    public String sex;
    public Cat(){

    }
    public Cat(String name,int age,String sex){
        super(name,age);
        this.sex=sex;
        System.out.println("sssss");
    }
    public void jump(){
        System.out.println(this.name+"跳跳");
    }
    public void eat(){
        System.out.println("吃吃吃吃");
    }
}
class Bird extends  Animal{
    public String yumao;
    public void fly() {
        System.out.println("飞飞");
    }
}

下面可以看一下关于多态的理解与应用

class Shape { 
    public void draw() {  
           // 啥都不用干   
   } 
 } 
 
class Cycle extends Shape {  
   @Override     public void draw() {    
        System.out.println("○");  
    } 
} 
 
class Rect extends Shape {  
   @Override     public void draw() {   
         System.out.println("□"); 
      } 
 } 
 class Flower extends Shape {  
      @Override     public void draw() {   
          System.out.println("♣");   
       } 
 }
 public class Test {   
     public static void main(String[] args) {     
          Shape shape1 = new Flower();     
          Shape shape2 = new Cycle();     
          Shape shape3 = new Rect();    
          drawMap(shape1);      
          drawMap(shape2);    
          drawMap(shape3);  
         } // 打印单个图形    
        public static void drawShape(Shape shape) {       
            shape.draw(); 
        } 
 }

当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当 前的 shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现 (和 shape 对应的实例相关), 这种行为就称为 多态。

向上转型,也就是父类引用子类对象,并且重写了父类的方法且调用
向下转型,就是把父类向子类转,但是必须要先进行向上转型,不然的话就会出出现类型转换错误
必须检查这个对象是不是父类的实例,不是的话就不能进行向下转型

 if(animal instanceof Cat ) {
            Cat cat = (Cat)animal ;
            cat.jump();
        }

就以这个为例,Cat明显不是Animal的实例,因此不能向下转型。

使用多态的好处是什么?

  1. 类调用者对类的使用成本进一步降低. 封装是让类的调用者不需要知道类的实现细节. 多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.
    继承与多态就说这些了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值