java 的三大特性:封装,继承,和多态。
今天我学习了Java的多态的内容,这边写出来以供探讨以及指正。
我所理解的多态即发出一条同样的指令,不同的对象接收指令并且执行会得到不一样的结果。比如 我们发出叫的指令,猫接收指令并且叫“喵”,狗接收指令叫“汪”,羊接收指令叫“咩”,这就是不同的对象实现相同的指令得到不一样的结果,这就是java多态的体现。
前面解释了多态的定义,下面我们说多态的分类,可以分为编译期多态和运行期多态,编译期多态我们同可以通过方法的重载进行实现,而运行期多态我们可以通过向上转型,动态绑定进行实现。
一、方法重载
方法的重载即在一个类内我们可以定义两个及以上具有相同名称的方法,但是他们的参数必须不同(参数类型,参数数量,参数顺序),即可认定他们是不同的方法,可以写相同的方法名执行不同的动作。但是要注意,方法的权限修饰符,返回类型不可以作为重载区分的标记。方法的重载可以实现编译期的多态。
二、向上转型和动态绑定
向上转型:即子类对象的引用赋值给父类对象,例如:
定义父类
Class Father(){}
定义子类
Class Son extends Father{
public static void main(String[] args){
Father father=new Son();
}
}
这样就可以用父类的句柄去引用子类的对象了。
动态绑定:绑定即将方法的调用和方法的主体连接到一起就称为绑定,动态绑定即在程序运行期间判断对象的类型并且调用适当的方法。
向上转型和动态绑定我们可以通过继承重写,接口实现。
我把抽象类归结到了继承重写里面了。抽象类是继承的一种特殊形式。继承的多态实现可以理解为子类继承了父类并且拥有处理父类所有公开的方法的权限,子类可以将父类的方法进行重写,然后将子类的对象引用赋值给父类对象句柄,即可以直接使用父类的对象句柄调用方法,在运行期间,如果方法在子类内被重写,程序就会调用子类重写的方法进行实现,不同的子类可以写不同的实现方式,这样就实现了多态。而抽象类就是特殊的继承了,因为一般作为父类来说,都是抽象的,实例化不具有实际意义的,所以我们干脆将类定义为抽象类,用abstract进行修饰,抽象类内必有一个方法是抽象方法,抽象方法没有实现体,只有方法名,这样我们就不可以将抽象类进行实例化,他只能作继承父类使用。下面我们举一个例子:
Class Father{
public void sad(){
System.out.println("Im sad,but i can't cry"); //父类的方法sad
}
}
Class Son extends Father{
public void sad(){
System.out.println("Im sad too,but i can cry"); //子类的同样方法sad;
}
public static void main(String[] args){
Father father=new Son(); //向上塑形,即用父类的句柄引用子类对象
father.sad(); //动态绑定,在运行期判断对象的实际类型判断并绑定适合的方法。
}
}
//执行结果为 Im sad too,but i can cry 调用的是子类的方法。
//抽象类的实现
//定义一个实例化无意义的抽象类,抽象类是对类的相似进行提取和抽象出来的
abstract class Animal {
public abstract void shout(); //定义抽象类动物,动物是高度抽象的且实例化无意义的。定义抽象方法叫和跑。
public abstract void run();
}
class Dog extends Animal {
public void shout{
System,.out.println("汪");
System,.out.println("狗在跑"); //定义子类,对抽象类的抽象方法进行了实现,若子类继承了抽象类并且不对他的抽象方法进行实现,则子类必须定义为抽象类
}
}
class Cat extends Animal {
public void shout{
System,.out.println(“喵");
System,.out.println("猫在跑");
}
public static void main(String[] args){
Animal animal;
Dog dog=new Dog();
Cat cat=new Cat(); //向上塑形,即用父类的句柄引用子类对象
animal=dog;
animal.shout();
animal.run();
animal=dog;
animal.shout();
animal.run(); //动态绑定,在运行期判断对象的实际类型判断并绑定适合的方法。
}
}
//输出结果为 汪
狗在跑
喵
猫在跑
同样是父类animal执行相同的指令,因为绑定的对象不同导致了结果的不同。
多形性的还有一种实现方式是使用接口,接口使用interface关键字进行修饰,接口只能进行方法的定义,不可以进行方法的实现,接口内可以定义成员变量,但是成员变量默认为static final类型,所以他们必须得到初始化。并且不允许对其进行二次修改或者二次绑定,实现接口的类必须实现接口全部的方法。使用接口的句柄引用实现类的对象,从而可以实现同样的句柄调用方法可以和不同对象的方法实现进行绑定。需要注意的是实现类可以实现多个接口,多个接口用逗号隔开。下面就是例子。
public interface Socket{
public void electrify(); //定义插座行为 通电。
}
public class Lamp implement Socket {
public void electrify(){ //灯实现了插座的接口
System.out.println("我通电 我发光");
}
}
public class ElectricKettle implement Socket {
public void electrify(){ //热水壶实现了插座的接口
System.out.println("我通电 我发热");
}
}
public class Action{
public static void start(Socket socket){
socket.electrify();
}
public static void main(String[] args){
start(new ElectricKettle()); //动态方法的绑定,action里的参数类型是接口Socket,但是实现时输入的参数类型是他的不同实现类
start(new Lamp ());
}
}
//运行结果 我通电 我发热
我通电 我发光
这就是java实现多形性的几种基本方式。如有不足,欢迎留言指正