Java中多态性的体现
多态是同一个行为具有多个不同表现形式或形态的能力。
Java中多态分为3类:
- 方法多态
- 参数多态
- 子类型多态
下面让我们逐一进行讨论。
一.方法多态
所谓方法多态就是对方法的重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
例:
public class ConstructorTest
{
public String name;
public String color;
public double weight;
public ConstructorTest() {}
public ConstructorTest(String name, String color)
{
this.name = name;
this.color = color;
}
public ConstructorTest(String name, String color, double weight)
{
this(name,color);
this.weight = weight;
}
public static void main(String[] args)
{
ConstructorTest mm = new ConstructorTest();
ConstructorTest mm2 = new ConstructorTest("guilan", "blue");
ConstructorTest mm3 = new ConstructorTest("kaixing", "green", 16);
System.out.println(mm3.name);
}
}
客户端的输入到底匹配哪个构造器,是在编译阶段静态检测负责的,根据参数列表选择相应构造器,而重写(Override)则是在运行时进行动态检查。
二.参数多态
参数多态就是泛型的使用。
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型类:
泛型类的声明和非泛型类的声明类似,只是在方法名后面加上一个“标签”—声明一种特殊类型。
例:
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<String> stringBox = new Box<String>();
integerBox.add(new Integer(10));
stringBox.add(new String("软件构造"));
System.out.printf("整型值为 :%d\n\n", integerBox.get());
System.out.printf("字符串为 :%s\n", stringBox.get());
}
}
编译以上代码,运行结果如下所示:
整型值为 :10
字符串为 :软件构造
上述代码中就是泛型,在泛型类中直接用T类型来定义属性,第一次不熟练其实就可以把它当作一个不同的String或者Integer来使用,在main方法中T被实例化成Sting和Integer类型,注意T只能被实例化成对象数据类型,而不能是基本数据类型。
泛型接口:
同理泛型接口的定义与普通接口相似,在接口名后加上“标签”
例:
interface Info<T>{
public T getValue();
}
class InfoImpl implements Info {
public String getVar() {
return null;
}
}
在进行接口实现时可以将T实例化成各种对象数据类型
泛型的使用一定程度上提高了代码的复用性。
三.子类型多态
子类型多态表现为子类继承父类
当一个子类型实例出现在父类型的的上下文中时,在实例上执行一个父类型的操作最终执行的会是子类型的版本。这要求子类型的规约不能弱于父类型,满足LSP原则。
例:
总结
Java的多态性质是很重要的性质,包含了三个方面,并为后续复用性奠定基础,需要细细理解!