Java SE 019 多态详解

(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

Java SE 019 多态详解

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

Parent p = new Child();

(1)p可以指向生成出来的Child的那个对象。换句话说,就是父类的引用指向了生成了子类的那个实例。

(2)p指向谁,就会去调用谁的方法,当前指向的是Child()的一个对象,所以它调用的就是Child类对象的方法。而不是Parent的方法。

(3)多态无处不在,没有多态,很多东西实现起来是很繁索的。非常麻烦的,而且会造成很多重复的工作。

(4)p虽然是指向子类型的一个引用,但是这个p是个什么类型的,是Parent类型的,Parent这个类型有这个sing()方法吗?它没有这个sing()方法。对于现在写的这种形式来说,要求这个p去指向一个子类的对象,并且去调用子类的某个方法,那么这个方法在父类里面也必须要存在,因为这个引用p它本身是父类型的。它是什么类型的,它才能去使用什么类型的方法,虽然它实际指向的是一个子类的对象,但是p本身还是一个父类型的一个的引用,也就是说它是一个父类型的变量,你不可能说我父类型的变量没有,而子类型里面有,我就能去调用,它是调用不了的。

(5)代码如下:

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”);
    }
}

(6)注意

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

2.小结

(1)Parent p = new Child();

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

3.向下的类型转换

(1)父类到子类,父类在上面,子类在下面,因此称作向下类型转换。

(2)向下类型转换的一个原则是看,Parent p = new Child();引用p实际指向的是什么,就可以将它转换成什么类型的引用。因为p实际指向的是Child类对象,所以就可以转换为Child对象的引用,

(3)Child c = (Child) p;

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

例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!");
	}
}

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

5.1向上类型转换(upcast)

(1)比如说将Cat类型转换为Animal类型,即将子类型转换为父类型。

(2)对于向上类型转换,不需要显示指定(如例3)。即不需要在前面加上“()”,当然写上也可以。

5.2向下类型转换(downcast)

(1)比如将Animal类型转换为Cat类型。即将父类型转换为子类型。

(2)对于向下类型转换,必须显示指定(必须要使用强制类型转换)。

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

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

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

(1)如果父类有3个方法,子类继承过来了或者重写了,此时使用强制类型转换,其实意义不大。

(2)因为使用的话,也是调用的子类的3个方法而已。

(3)不使用也是调用的这3个方法,但是父类有的,子类可以添加。

(4)在子类再添加到5个方法,如果使用a来调用方法的时候,就只能调用子类当中存在于父类里面的那3个方法,也就是父类里面声明过的那3个方法。另外的子类新增加的2个方法,就根本调用不了,因为它的类型是Animal类型的。

(5)要想调用子类新添加的2个方法,这时候就必须要使用向下类型转换,将它转换成子类型的,转换成子类型之后,才能使用子类又新添加的方法。

为使用的话,也是调用的子类的3个方法而已。

(3)不使用也是调用的这3个方法,但是父类有的,子类可以添加。

(4)在子类再添加到5个方法,如果使用a来调用方法的时候,就只能调用子类当中存在于父类里面的那3个方法,也就是父类里面声明过的那3个方法。另外的子类新增加的2个方法,就根本调用不了,因为它的类型是Animal类型的。

(5)要想调用子类新添加的2个方法,这时候就必须要使用向下类型转换,将它转换成子类型的,转换成子类型之后,才能使用子类又新添加的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值