java中的多态

java中的多态及运用

多态属于面向对象语言的三大特性之一,简单说就是同一个对象在不同时刻表现出不同的形态。在java中,多态的运用需要有以下三个条件:

  1. 有继承/实现的关系
  2. 有方法重写
  3. 有父类引用指向子类对象
    举个例子,我们建立一个动物类,如下:
public class Animals {
    public void eat(){
        System.out.println("动物吃肉");
    }
}

我们在定义一个猫类,继承自动物类,如下:

public class cat extends Animals{
    @Override//多态需要重写方法,我们重写eat方法
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void play(){
        System.out.println("猫玩毛线球");
    }
}

接下来,我们建立测试类,在其中运用多态建立对象:

public class Demo {
    public static void main(String[] args) {
        Animals a = new cat();
        a.eat();
    }
}

在main方法中,我们创建了一个cat的对象a,其引用父类类型,即父类引用指向子类对象,那么此时这个对象a的创建就运用了多态。最后,上面这个例子输出的结果就是
在这里插入图片描述

多态的成员访问特点

在编译时,我们看到的是多态对象的类型,即他的父类,如上面a对象的类型就是Animals,那么编译时,所调用的变量必须是Animals中有的,cat类中独有的变量不能被编译,会报错;而在我们调用的方法中,也需要在父类中有才能通过编译。
执行时,成员变量的值是父类中的成员变量的值,而成员方法因为有重写的缘故,优先执行子类中重写过的方法,否则执行父类中的成员方法。
总结:
对成员变量来说,编译和执行都看对象引用类型,如:

Animals a = new  cat();
System.out.println(a.age);

这里对象a是cat类,但他的引用类型为它的父类Animals,因此编译和执行时都用的父类Animals中的成员变量age。
对成员方法来说,编译看的是引用类型的成员方法,但因为重写的缘故,执行时优先执行重写后的子类cat中的成员方法。

2021年5月29日更新

那么如果我们非要使用子类对象中的特有方法时,该怎么操作呢?我们可以使用类型强制转换,即向下转型,以上面的例子来说,我们要在main方法中调用子类对象中play方法,我们可以这样做:

	Cat c= (Cat)a;
        c.play();
        System.out.println(a);
        System.out.println(c);

我们可以看拿到,我们将一个Animals类型的通过强制转换变成了cat类型,那么cat类型的c变量当然就可以调用cat类中特有方法,我们再输出a和c的地址值,结果如下:
在这里插入图片描述
我们发现此时a和c 的地址值是相同,表示这是一同一个变量,至此,我们就可以做到在多态下使用子类特有的方法。

2021年5月30日更新

除了上述的通过继承实现对象的多态,还可以通过接口实现来实现对象的多态。接口是对动作的抽象化,而类是对对象的抽象化。
举例如下:
创建eating的接口,并提供抽象方法eat。

public interface eating {

    public void eat();
}

创建cat类,这个类实现了eating接口。

public class Cat implements eating{
    @Override
    public void eat() {
        System.out.println("猫现在学会吃饭了");
    }
}

最后在main方法中,捅多态创建接口对象

public class InterfaceDemo {
    public static void main(String[] args) {
        eating c = new Cat();
        c.eat();
    }
}

这个就是通过接口实现来使用多态
结果如下:
在这里插入图片描述

总结:多态的形式主要有三种,具体类多态,抽象类多态,接口多态,后两种使用更加广泛
多态的前提:有继承或实现关系,有方法重写,有父(类/接口)引用只想子(类/实现)对象。

仅供个人学习使用,如有错误请指出,谢谢

### 多态的基本概念 多态是面向对象编程中的一个核心特性,它允许子类对象替换父类对象。这意味着可以使用父类的引用指向子类的对象,并调用在子类中重写的方法[^1]。 ### 多态的具体体现 多态主要体现在方法的覆盖(也称为重写)上,即子类可以提供特定于自身的实现,而这些实现可以在不改变接口的情况下被调用[^1]。 ### 入门案例 考虑一个简单的例子,我们有一个`Animal`类,它有一个`sound()`方法。我们可以创建`Dog`和`Cat`类作为`Animal`的子类,并重写`sound()`方法来发出不同的声音。 ```java class Animal { void sound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { void sound() { System.out.println("Barking..."); } } class Cat extends Animal { void sound() { System.out.println("Meowing..."); } } ``` 在这个例子中,尽管`myAnimal`是一个`Animal`类型的引用,但它可以指向`Dog`或`Cat`的对象,并且会调用相应对象的`sound()`方法。 ### 多态的转型 #### 向上转型 向上转型是指将子类对象赋值给父类引用的过程,这是自动完成的,不需要显式的转换。 ```java Animal myAnimal = new Dog(); // Upcasting ``` #### 向下转型 向下转型是指将父类引用转换为子类类型的过程,这需要显式的转换,并且只有当引用实际上指向的是该子类的一个实例时才是合法的。 ```java Animal myAnimal = new Dog(); Dog dog = (Dog) myAnimal; // Downcasting ``` #### 代码示例 ```java public class TestPolymorphism { public static void main(String[] args) { Animal myAnimal = new Animal(); // Animal object Animal myDog = new Dog(); // Animal reference but Dog object Animal myCat = new Cat(); // Animal reference but Cat object myAnimal.sound(); myDog.sound(); // Runs Dog's sound method myCat.sound(); // Runs Cat's sound method } } ``` #### 转型的异常 ##### 类型转换异常 如果尝试将一个对象转换为其实际类型不是的目标类型,则会抛出`ClassCastException`。 ```java Animal myAnimal = new Animal(); Dog dog = (Dog) myAnimal; // Throws ClassCastException ``` ##### `instanceof` 比较操作符 为了避免`ClassCastException`,可以使用`instanceof`关键字来检查对象是否是指定类型。 ```java if (myAnimal instanceof Dog) { Dog dog = (Dog) myAnimal; } ``` ### 动态绑定(重点) 动态绑定(或后期绑定)指的是在运行时根据对象的实际类型来决定调用哪个方法的过程。这是多态的基础,也是Java中实现多态的关键机制。 ### 应用 #### 多态数组 多态数组指的是可以存储不同子类对象的数组,而数组的声明类型是它们共同的父类。 ```java Animal[] animals = new Animal[3]; animals[0] = new Dog(); animals[1] = new Cat(); animals[2] = new Animal(); for (Animal animal : animals) { animal.sound(); } ``` #### 多态参数 多态参数允许方法接受任何子类类型的参数,从而实现更通用的设计。 ```java public void makeSound(Animal animal) { animal.sound(); } ``` ### 多态的优点 - **可扩展性**:可以轻松添加新的子类而无需修改现有代码。 - **可维护性**:由于代码更加通用,因此更容易维护。 - **代码复用**:可以通过继承复用代码,并通过多态提供灵活性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值