14面向对象—多态

面向对象的第三大特征就是多态(Ploymorphism)

  1. 多态的实现条件
    Java实现多态的必要条件:继承、重写,当编译时类型和运行时类型不一致,就会出现多态。
    父类声明的变量可以引用所有子类的对象,这是多态实现的基础;我们只有在运行的时候才会知道引用变量所指向的具体实例对象。
  2. 多态的作用
    把不同的子类对象都当作父类对象;来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。简而言之,就是用父类或接口的引用变量指向子类的对象
  3. 应注意的问题
    (1)、静态方法不能被重写,所以静态方法没有多态性
    (2)、成员变量不具备多态性,成员变量的值取决于引用属性的类
    (3)、成员方法编译时应先检查引用变量所属类中是否有调用的方法;运行时调用的实际对象是所属类中的重写方法。
    (4)、一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中特有的属性和方法
  4. 案例
    动物类(父类)
public class Animal {
    public void shout(){
        System.out.println("动物在叫");
    }
    public void eat(String food){
        System.out.println("在吃"+food);
    }
}

猫类和狗类(子类)

//猫类
public class Cat extends Animal{
    @Override
    public void shout() {
        System.out.println("喵喵");
    }
}
//狗类
public class Dog extends Animal{
    @Override
    public void shout() {
        super.shout();
        System.out.println("汪汪汪");
    }
    @Override
    public void eat(String food) {
        System.out.println("小狗爱吃骨头,不爱吃"+food);
    }
}

测试类

public class Test {
    //多态的条件:继承和重写;适用于方法,不用于属性
    public static void main(String[] args) {
        //正常情况
        Animal animal = new Animal();
        animal.shout();
        Dog dog = new Dog();
        dog.shout();
        Cat cat = new Cat();
        cat.shout();

        //多态
        Animal a = new Dog();
        a.shout();  //此时调用的还是Animal里面默认的方法
        Dog d = (Dog) a;  //强制类型转换
        d.shout();  //此时就可以调用重写的shout方法了
        Animal an = new Cat();
        Cat c = (Cat)an;
        c.shout();
        //传入参数的多态
        test(animal);
        test(c);
        test(d);
    }
    public static void test(Animal animal){
        animal.shout();
    }
    public static Animal test1(Animal animal){
        //返回值的多态:可以返回d2,也可以返回c2
//        Dog d2=new Dog();
//        return d2;
        Cat c2 = new Cat();
        return c2;
    }
}
### 面向对象编程中的多态概念 多态面向对象编程的核心特性之一,它允许不同类型的对象对同一消息作出不同的响应。通过多态机制,程序能够以统一的方式处理多种类型的对象,从而提高代码的灵活性和可扩展性[^1]。 #### 动态多态与静态多态 动态多态通常指运行时多态,主要依赖于继承和方法重写来实现。当子类覆盖父类的方法时,在运行期间会根据实际的对象类型调用对应的方法版本。这种形式的多态适用于实例方法,而不支持`static`方法,因为`static`方法属于类本身而非具体对象,因此无法被重写[^2]。 静态多态则发生在编译阶段,典型例子包括函数重载和运算符重载。在这种情况下,基于参数的数量、顺序或者数据类型的不同,相同名称的函数可以执行完全不同的操作。 #### 向上转型及其应用场合 向上转型是指将子类对象赋值给父类引用的过程。这一过程自动发生且无需强制转换。向上转型常见于两种场景:作为方法参数传递以及用于变量声明中的赋值操作。然而需要注意的是,一旦进行了向上转型,则仅能访问那些定义在父类里的属性或方法;如果尝试调用未由父类声明但存在于子类内的功能,将会引发错误[^3]。 以下是关于Java语言的一个简单示例展示如何利用向上转型配合多态: ```java class Shape { public void draw() { System.out.println("Drawing a shape"); } } class Circle extends Shape { @Override public void draw() { System.out.println("Drawing a circle"); } public void roll() { System.out.println("Circle is rolling..."); } } public class TestPolymorphism { public static void main(String[] args) { Shape s = new Circle(); // Upcasting from Circle to Shape s.draw(); // Outputs: Drawing a circle due to polymorphic behavior // The following line would cause compile-time error since 'roll' method isn't part of the declared type (Shape). // s.roll(); } } ``` 对于像JavaScript这样的弱类型脚本语言来说,由于其独特的原型链结构,也可以模拟出类似的多态效果。下面给出了一种简单的做法: ```javascript function Animal(sound) { this.sound = sound; } Animal.prototype.makeSound = function () { console.log(this.sound); }; // Define subclasses with their own sounds. const Duck = Object.create(Animal.prototype); Duck.constructor = function () {this.sound='Quack!';}; new Duck().constructor(); const Chicken = Object.create(Animal.prototype); Chicken.constructor = function () {this.sound='Cluck!';}; new Chicken().constructor(); let animalsArray = [new Duck(), new Chicken()]; animalsArray.forEach(function(animal){ animal.makeSound(); // Polymorphically calls appropriate version based on actual object at runtime. }); ``` 尽管这里采用构造器模式创建了两个“物种”,并通过数组迭代实现了某种意义上的多态行为演示[^4],但这并非严格意义上符合传统OOP理论下的多态定义。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值