Java SE 019 多态详解

Java SE 019 多态详解

前言:此笔记为圣思园张龙老师讲述的java视频课程笔记,自己看视频学习时记录的,用于积累与复习,在此分享给学习软件编程的兄弟姐妹们,以供参考。

一.父类型的引用可以指向子类型的对象。

Parent p = new Child();
解说:
(1)p可以指向生成出来的Child的那个对象。换句话说,就是父类的引用指向了生成了子类的那个实例。
(2)p指向谁,就会去调用谁的方法,当前指向的是Child()的一个对象,所以它调用的就是Child类对象的方法。而不是Parent的方法。
(3)多态无处不在,没有多态,很多东西实现起来是很繁索的。非常麻烦的,而且会造成很多重复的工作。
(4)p虽然是指向子类型的一个引用,但是这个p是个什么类型的,是Parent类型的,Parent这个类型有这个sing()方法吗?它没有这个sing()方法。对于现在写的这种形式来说,要求这个p去指向一个子类的对象,并且去调用子类的某个方法,那么这个方法在父类里面也必须要存在,因为这个引用p它本身是父类型的。它是什么类型的,它才能去使用什么类型的方法,虽然它实际指向的是一个子类的对象,但是p本身还是一个父类型的一个的引用,也就是说它是一个父类型的变量,你不可能说我父类型的变量没有,而子类型里面有,我就能去调用,它是调用不了的。代码如下:

public class PolyTest{
    public static void main(String [] args){
        Parent p = new Child();//多态
        p.sing();
        /*执行此条语句的时候,它首先会检查父类里面是否有sing()这个方法,如果有这个方法的话,它再去子类里面去调用不管是继承过来的,还是重写之后的那个版本的sing()方法。*/
    }
}

class Parent{
    //父类没有sing()方法 
}

class Child{
    public void sing(){
        System.out.println(“parent”);
    }
}

注意:
必须要在父类方法中也要存在这样一个sing()方法,因为这是由p的类型Parent来决定的。所以在使用父类型的引用去指向子类型的对象,去调用子类的某个方法的时候,这个方法一定要确保在父类里面要出现过,或者说父类里面一定要定义过这个方法才可以,否则编译的时候会出错。因为它在父类型的时候,它找不到这个sing()方法。

二.小结

Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有sing()方法,如果没有则编译错误,如果有,再去调用子类的sing()方法。

三.向下的类型转换

(1)父类到子类,父类在上面,子类在下面,因此称作向下类型转换。
(2)向下类型转换的一个原则是看,Parent p = new Child();引用p实际指向的是什么,就可以将它转换成什么类型的引用。因为p实际指向的是Child类对象,所以就可以转换为Child对象的引用,即:
Child c = (Child) p;

四.指向谁就调用谁的方法

例1:

public class polytest2{
	public static void main(string [] args){
		animal animal = new cat();
		animal animal2 = new animal();
		/*
		  将anmal2指向animal所指向的cat对象
		  指向谁就调用谁的方法
		*/
		animal2 = animal;
		animal2.sing();
	}
}

class animal{
	public void sing(){
		system.out.println("animal is sing!");
	}
}

class dog extends animal{
	public void sing(){
		system.out.println("dog is sing!");
	}
}

class cat extends animal{
	public void sing(){
		system.out.println("cat is sing!");
	}
}

例2:

public class polytest2{
	public static void main(string [] args){
		animal animal = new cat();
		animal animal2 = new Animal();
		/*指向谁就调用谁的方法,此处将animal指向
                 animail2指向的Animal的对象
		*/
		animal = animal2;
		animal.sing();
	}
}

class animal{
	public void sing(){
		system.out.println("animal is sing!");
	}
}

class dog extends animal{
	public void sing(){
		system.out.println("dog is sing!");
	}
}

class cat extends animal{
	public void sing(){
		system.out.println("cat is sing!");
	}
}

例3:

public class polytest2{
	public static void main(string [] args){
		Cat cat = new Cat();
		/*
		cat 现在指向的是子类的对象,将它赋给Animal对象,
		变成了Animal类型的引用指向了子类的对象,因此就
		调用子类Cat类的sing()方法
		*/
		Animal animal = cat;
		animal.sing();
	}
}

class animal{
	public void sing(){
		system.out.println("animal is sing!");
	}
}

class dog extends animal{
	public void sing(){
		system.out.println("dog is sing!");
	}
}

class cat extends animal{
	public void sing(){
		system.out.println("cat is sing!");
	}
}

例4:

public class polytest2{
	public static void main(string [] args){
		/*
		Animal对象的引用指向了父类的引用
		接下来进行强制类型转换,强制将animal
		转换为一个cat,因为Cat是Animal的一个子
		类,在编译的时候,java只知道这个信息,
		但是这个Animal到底指向的是谁,只有到
		执行的时候,才能确定下来。一个Animal的
		对象在执行的时候,强制的转换成Cat对象。
		就好比人强制转换成男人,从常理上来说是
		错误的。指向谁才能转换成谁,我指向的是Cat
		才能转换成Cat,现在我指向的是Animal,是不
		能随便转换成Cat的。
		*/
		Animal animal = new Animal();

		Cat cat = (Cat) animal;
	}
}

class animal{
	public void sing(){
		system.out.println("animal is sing!");
	}
}

class dog extends animal{
	public void sing(){
		system.out.println("dog is sing!");
	}
}

class cat extends animal{
	public void sing(){
		system.out.println("cat is sing!");
	}
}

五.一共有两种类型的强制类型转换

1.向上类型转换(upcast)

比如说将Cat类型转换为Animal类型,即将子类型转换为父类型。对于向上类型转换,不需要显示指定(如例3)。即不需要在前面加上“()”,当然写上也可以。
### 2.向下类型转换(downcast)
比如将Animal类型转换为Cat类型。即将父类型转换为子类型。对于向下类型转换,必须显示指定(必须要使用强制类型转换)。

Animal a = new Cat();
Cat c = (Cat)a;
c.sing();

调用a.sing()方法与调用c.sing()方法,结果是一样的.

六.那么我们为什么有些时候还要进行向下类型转换呢?

如果父类有3个方法,子类继承过来了或者重写了,此时使用强制类型转换,其实意义不大。因为使用的话,也是调用的子类的3个方法而已。不使用也是调用的这3个方法,但是父类有的,子类可以添加,在子类再添加到5个方法,如果使用a来调用方法的时候,就只能调用子类当中存在于父类里面的那3个方法,也就是父类里面声明过的那3个方法。另外的子类新增加的2个方法,就根本调用不了。因为它的类型是Animal类型的。要想调用子类新添加的2个方法,这时候就必须要使用向下类型转换,将它转换成子类型的,转换成子类型之后,才能使用子类又新添加的方法。

发布了134 篇原创文章 · 获赞 26 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/xiogjie_67/article/details/104372964