多态
目的:无论在项目最初创建时还是在需要添加新功能时都可以生长的程序。
多态的实现
发送消息给某个对象,让该对象自行决定响应何种行为。
通过将子类对象引用赋值给超类对象引用来实现动态方法调用。
接口 和 实现接口并覆盖接口中同一方法的几个不同的类体现的。
父类 和 继承父类并覆盖父类中同一方法的几个不同子类实现的。
例如:
DerivedC c2 = new DerivedC();
BaseClass a1 = c2; // BaseClass 基类,DerivedC是继承自BaseClass的子类
a1.play(); // play()在BaseClass,DerivedC中均有定义,即子类覆写了该方法
定义了一个BaseClass类型的引用,指向新建的DerivedC类型的对象。由于DerivedC是继承自它的父类BaseClass。
1>.所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的。
2>.同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
3>.对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法。
4>.变量不能被覆盖,如果在子类中”重写”了父类中的变量,那么在编译时会报错。
在运行时期,将根据a1这个对象引用实际的类型来获取对应的方法,所以才有多态性,一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
BaseClass a2 = new BaseClass();
DerivedC c1 = a2; // 出错
在Java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行,
c1=(Derived)a2;进行强制转换,也就是向下转型。
在项目中为什么要使用多态
首先,假设有这样一个系统:有一个动物园,效益还不错,买了只熊猫。
按照面向对象的思想,我们会抽象出来一个类,表示熊猫,其中有个eat ()方法。
public class XM {
public void eat() {
System.out.println("熊猫正在吃竹子!");
}
}
我们还会抽象出一个类,来代表饲养员。其中有个feed()方法,需要一个动物类型作为参数,我们先传入一个XM类型的参数
// 这是我们的核心业务类
public class Feeder {
public void feed(XM xm) {
xm.eat();
}
public static void main(String args[]) {
Feeder d = new Feeder();
XM xm = new XM();
d.feed(xm);
}
}
这样写的代码偶合性太强了,如果我们的需求变了,这个动物园后来更有钱了,买了一只狮子,我们的系统只能修改。这就是原因,我们的系统会增加一个类,也有个eat()方法。
public class SZ {
public void eat() {
System.out.println("狮子正在吃肉! ");
}
}
核心业务类也要修改
public class Feeder {
public void feed(XM xm) {
xm.eat();
}
public void feed(SZ sz) {
sz.eat();
}
public static void main(String args[]) {
Feeder d = new Feeder();
XM xm = new XM();
d.feed(xm);
SZ sz = new SZ();
d.feed(sz);
}
}
以后的情况,我们可以把动物抽象出来:
public abstract class Animal {
/* 属性 */
// 让子类来运行
public void eat() {
}
}
public class XM extends Animal {
public void eat() {
System.out.println("熊猫正在吃竹子!");
}
}
public class SZ extends Animal {
public void eat() {
System.out.println("狮子正在吃肉! ");
}
}
public class Feeder {
private Animal animal;
public Feeder() {
}
public Feeder(Animal animal) {
this.animal = animal;
}
public void feed() {
animal.eat();
}
// 运用参数多态,以后不管买什么动物都可以
public void setAnimal(Animal animal) {
this.animal = animal;
}
public static void main(String args[]) {
Feeder f = new Feeder();
// 刚开始买只熊猫
XM xm = new XM();
f.setAnimal(xm);
f.feed();
// 再买只狮子
SZ sz = new SZ();
f.setAnimal(sz);
f.feed();
}
}
不管是XM还是SZ都是我们自己直接new出来的.我们可以设计一个工厂类,专门生产动物。
/**
*
* 我们将多态使用在方法的返回类型中
*
* Animal可以是抽象类,也可以是接口,XM和SZ分别继承该类或实现该借口
*/
public class AnimalFactory {
public Animal factory(String animalName) {
if (animalName.equals("XM")) {
return new XM();
} else if (animalName.equals("SZ")) {
return new SZ();
} else {
System.out.println("对比起,地球没有这种动物");
return null;
}
}
}
这是设计模式中的简单工厂模式
另外,在JDK中可以大量的看到多态的应用,比如在Object类中的equals(Object obj)方法中,参数是个Object
类型的参数,因为Object是Java中所有类的基类.,但是才传入参数的时候,可以传入任何一个类的对象,这就是多态的应用
使用多态可以解决项目中解偶合的问题,提高程序的可扩展性.是多态的一个具体的实现。
本文介绍了多态的概念及其在程序设计中的应用。通过实例说明如何使用多态减少代码耦合度,提高系统的可扩展性,并展示了多态在方法返回类型中的具体实现。
1370

被折叠的 条评论
为什么被折叠?



