详述java的多态

  • 什么是多态

在介绍多态之前,首先我们要明白多态是基于java中继承的延申,所以我们先创建一个子类与父类


public class Mammal{
	public void move() {
		System.out.println("移动");
	}//创建父类,添加方法move
}


public class Whale extends Mammal{
		
}
//创建子类,继承父类

我们知道,在java中有着数据类型的自动转换,比如 double price = 9,在这里,9其实是一个int类型,但可以通过这段代码使其转化为double类型,而其实java中的对象也有着相似的操作


public class Mammal{
	public void move() {
		System.out.println("移动");
	}
}


public class Whale extends Mammal{
        public void move() {
		System.out.println("用鳍摆动移动");//重写move方法
	}
	
        public static void main(String[] args) {
		Mammal mammal = new Whale();//自动类型转换:父类类型的变量指向其子类创建的对象 对象上转型  new Whale()上转型对象                                           

		mammal.move();//调用父类move方法
		}
}

正常情况下,我们创建子类对象应该用 Whale whale = new Whale();语句,但是在最后这段代码中,我们创建的子类对象是由父类类型的变量所指向的,这就叫做对象上转型。虽然我们重写了父类的方法,但最后我们调用的仍然是父类方法,那么最终输出什么呢?

我们看到,明明调用的是父类的方法,但由于该对象实质上仍然是子类所创建的,只是被父类变量所指向,执行时由于mammal存的是子类创建的对象,所以执行时执行的是子类中的方法。我们把这种现象称之为多态。

  • 注意事项

同时需要注意的是,我们把Mammal mammal = new Whale()等号的左边叫做编译体,右边叫做执行体,所以代码的编译在父类中进行,而执行在子类中进行,这也就导致了一件事情:父类中没有而子类中新增的方法和属性,不能被上转型对象调用


public class Mammal{
	public void move() {
		System.out.println("移动");
	}
}


public class Whale extends Mammal{
        public void move() {
		System.out.println("用鳍摆动移动");//重写move方法
	}
        public void eat(){
                System.out.println("吃东西");//新增eat方法
        }
	
        public static void main(String[] args) {
		Mammal mammal = new Whale();//创建上转型对象
		mammal.move();
                mammal.eat();//调用eat方法
		}
}

 在这段代码中我们在子类里新增了父类所没有的eat方法,程序报错,这其实是因为父类中没有该方法,于是在编译的时候就出现了问题,因此我们会发现mammal根本无法调用eat方法(新增属性也是如此,不再另外举例)

 那么如果我们想要让子类中新增的方法和属性被上转型对象调用,该怎么做呢?

答案:将上转型对象进行下转型


public class Mammal{
	public void move() {
		System.out.println("移动");
	}
}


public class Whale extends Mammal{
        public void move() {
		System.out.println("用鳍摆动移动");//重写move方法
	}
        public void eat(){
                System.out.println("吃东西");//新增eat方法
        }
	
        public static void main(String[] args) {
		Mammal mammal = new Whale();//创建上转型对象
		mammal.move();
                Whale whale = (Whale)mammal;//进行下转型
                whale.eat();//调用eat方法		
    }
}

我们使用的下转型语句Whale whale = (Whale)mammal 将子类对象重新转型为本类变量所指向的对象,因此就可以调用本类的新增对象和属性了

 另外,需要记住,在进行下转型之前必须先有上转型对象,否则就是简单的本类对象了,没有对象转型一说。

  • 多态的拓展

由于子类重写了方法,且进行了对象上转型操作后,执行的是子类的重写方法,父类的被重写方法其实没有意义,因此我们可以说多态的前提下,父类中被子类重写的方法没有必要有方法体


public class Mammal{
	public void move() {
	}//没有方法体的父类方法
}

public class Whale extends Mammal{
		public void move() {
			System.out.println("用鳍摆动移动");
		}
		
		public static void main(String[] args) {
			Mammal mammal = new Whale();
			mammal.move();//重写move方法后将子类对象上转型然后调用move方法
		}
}

像这样,程序一样可以正常运行,而这种情况下,我们可以在父类没有方法体的方法的访问控制符与修饰符之间加上abstract关键词使其变为抽象方法,而如果一个类中含有了抽象方法,那么就必须用abstract修饰,成为抽象方法

public abstract class Mammal{//因为含有抽象方法,该类必须加上abstract关键字成为抽象类
	public abstract void move() {
	}//没有方法体的父类方法加上abstract关键字成为抽象方法
}

public class Whale extends Mammal{
		public void move() {
			System.out.println("用鳍摆动移动");
		}
		
		public static void main(String[] args) {
			Mammal mammal = new Whale();
			mammal.move();//
		}
}

并且,如果一个抽象类下全都是抽象方法,我们就可以把它称为接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值