JAVA多态的使用

多态的使用

多态的引入

假设你想创建一个Dog专用List

public class MyDogList{
    private Dog[] dogs = new Dog[5];
    private int nextIndex = 0; // 增加新的Dog就加一
    
    public void add(Dog d) {
        if (nextIndex < dogs.length) { // 如果没有超过dogs的上线
            dogs.[nextIndex] = d;
            System.out.println("Dog added at" + nextIndex);
            nextIndex++; // 递增计数
        }
    }
}

但是,现在也要写出Cat用的

  1. 另外创建一个单独的MyCatList来处理Cat对象 (这样显然是不好的)

  2. 创建一个单独的DogAndCatList类,用addCat(Cat c) 与 addDog(Dog d) 来同时处理两个不同的数组实例,但是这样也不是很好

  3. 编写一个不同的AnimalList类让他来处理Animal所有的子类

    // 自己创建一个Animal通用List
    public class MyAnimal {
        // 这不是在创建Animal对象,只是保存Animal的数组对象
        private Animal[] animals = new Animal[5]; 
        private int nextIndex = 0;
        public void add(Animal a) {
            if (nextIndex < animals.length) {
                animals[nextIndex] = a;
                System.out.println("Animal added at" + nextIndex);
            }
        }
    }
    
    public class AnimalTestDrive{
        MyAnimalList list = new MyAnimalList();
        Dog d = new Dog();
        Cat c = new Cat();
        list.add(a);
        list.add(c);
    }
    

对象之母

Java中所有的类都是从Object这个类继承出来的

Object是所有类的源头,他是所有类的父类

可以把自己的代码想象成

public class Dog extends Object(){}

没有直接继承过其他类的类会是隐含的继承对象

所以就算Dog或Cannie没有直接extend对象,还是会通过Animal来继承对象

终极对象

// 一.equals
Dog a = new Dog();
Cat c = new Cat();
if (a.equals(c)) {
    System.out.println("true");
} else {
    System.out.println("true");
}
// 输出结果为false

// 二.getClass()
Cat c = new Cat();
System.out.println(c.getClass());
// 输出结果是 class Cat

// 三. hasCode()
Cat c = new Cat();
System.out.println(c.hasCode());
// 输出结果是 8202111

// 四.toString()
Cat c = new Cat();
System.out.println(c.toString());
// 输出结果是 Cat@7d277f
  • Object这个类是抽象类嘛?
    • 不是
  • Object类是具体的,怎么会允许有人去创建Object的对象?
    • 因为有时候就是会需要一个通用的对象.一个轻量化的对象,他是最常见的用途是在线程的同步化上

使用Object类型的多态引用是会付出代价的

ArrayList<Object> myDogArrayList = new ArrayList<Object>(); // 保存对象的
Dog aDog = new Dog();
myDogArrayList.add(aDog);

如果是如上述代码一样存储Dog对象,那么取出Dog对象的时候会引发什么事情?

Dog d = myDogArrayList.get(0);

这段代码将无法编译!对ArrayList 调用get()方法会返回Object类型,编译器无法确认它是Dog!!!

任何ArrayList去除来的东西都会被当作Object类型的引用而不管它原来是什么

public void go(){
    Dog aDog = new Dog();
    Dog sameDog = getObject(aDog);
}
public Object getObject(Object o) {
    return o;
}

无法通过编译,虽然这个方法会返回一个Dog,但是编译器认为这只能赋值给Object类型的变量

public void go(){
    Dog aDog = new Dog();
    Object sameDog = getObject(aDog);
}
public Object getObject(Object o) {
    return o;
}

这样会过关,因为你可以赋任何值给Object类型的引用,平且每个东西都能对Object通过IS-A测试

编译器是根据引用类型来判断有哪些method可以调用,而不是根据Object确实的类型

就算你知道对象有这个功能,编译器还是会把它当作一般Object来看待,编译器只管引用的类型,而不是对象的类型

上述的sameDog就不可以在调用Dog身上的方法了,只能引用Object身上的方法

“多态"意味着"很多形式”

你可以把Snowboard当作Snowboard或者Object

image-20211218144707125

当你把对象装进ArrayList时,不管它原来是什么,你只要把它当作是Object.

从ArrayList取出引用时,引用类型只会是Object

转化为原来的类型
Object o = al.get(index);
Dog d = (Dog) o; // 将类型转化成Dog
d.roam();

如果不能确定它是Dog可以使用instanceof这个运算符来检查,若是类型转化错误,会遇到ClassCastException异常并且终止.

if (o instanceof Dog) {
    Dog d = (Dog) o;
}

g) o; // 将类型转化成Dog
d.roam();


如果不能确定它是Dog可以使用instanceof这个运算符来检查,若是类型转化错误,会遇到ClassCastException异常并且终止.

```Java
if (o instanceof Dog) {
    Dog d = (Dog) o;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值