多态&抽象类&接口的综合解释

#多态

-多态是指针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法,是一个在面向对象编程中非常重要的特性,英文名为 Polymorphic .

多态的基础是向上转型和覆写(@override)

  • 向上转型和覆写的详细解释 :
//Person为父类型 
class Person {
	public void sayHello {
		System.out.println("class-Person Hello!");
	}
}
class Individual extends Person {
	@Override
	public void sayHello(){
		System.out.println("class-Individual Hello!")
	}
	public void sayGoodBye(){
		System.out.println("Good Bye!");
	}
}

针对上述代码的一个典型的 向上转型的 例子 :

Person p = new Student() ;
p.sayHello() ;    //output : class-Individual Hello!
p.sayGoodBye() ; //compilerError!!!

上述代码用一个父类型的引用变量指向了一个子类型的实例,我们可以从上述代码获得启发 , 即 :
引用变量的类型(就如上述的Person), 限定了引用变量可以访问的子类实例的字段和方法的范围 , 这个范围就是子类从父类继承下来的字段和方法 , 如果方法被覆写,则访问的是子类中实际存在的overrider方法。更简洁的说就是:

Java的实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。这个特性就是多态 —廖雪峰

#抽象类

如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名 , 目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法 :

class Person {
	public abstract void run() ;   //Complier Error : The type Person must be an abstract class to define abstract methods ; 
}

编译器会告诉我们 , 无法编译Person类 , 因为它包含抽象方法 。
必须把Person类本身也声明为abstract , 才能正确编译它 :

abstract class Person {
	String name = "yangshuhui" ; 
	int age = 20 ;  
	
	public abstract void run() ;  //一定要被覆写
	public void sayHello() {
		System.out.println("Hello , My friends!");  //自己决定要不要在子类中覆写 ;
	}; 
}

抽象方法本身是无法执行的 , 所以 , Person类无法被实例化 。
这时候Person就是一个抽象类 ,抽象类的特点是无法被实例化,其被设计成只能用于继承 , 因此 , 抽象类可以强迫子类实现其定义的抽象方法 , 否则编译会报错。因此 , 抽象方法实际上是定义了“规范” ;

#面向抽象编程

本质 :

  • 上层代码只定义规范 (例如: abstract class Person );
  • 不需要子类就可以实现业务逻辑(正常编译);
  • 具体的业务逻辑由不同的子类实现 ,调用者并不关心 ;

#接口

在抽象类中 , 抽象方法本质上是定义接口规范 : 即规定高层类的接口 , 从而保证所有子类都有相同的接口实现 , 这样 , 多态就能发挥出全部威力 ;
在某种特殊的情况下 , 一个抽象类没有字段 , 所有方法全部是抽象方法 :

abstract class Person {
	public abstract void run() ;
	public abstract String getName() ;
}
class Student extends Person {
	@Override 
	public void run() {...}
	@Override 
	public String getName() {...} 
}

在这种情况下 , 可以把抽象类改写为接口 : interface , 在Java中 , 使用interface可以声明一个接口 :

interface Person {
	void run() ;
	String getName() ; 
} 
//当一个具体的class去实现一个interface时 , 需要使用implements关键字 : 
class Student implements Person {
	private String name ;
	public Student(String name){
		this.name = name ;
	}
	@Override 
	public void run() {
		System.out.println(this.name+" run");
	}
	@Override
	public String getName() {
		return this.name ;
	}
}

接口就是比抽象类还要抽象的纯抽象接口 ,因为它连字段都不能有 。 接口定义的所有方法默认都是public abstract , 所以这两个修饰符都不需要写出来(写不写效果都一样)。
接口的特殊之处在于 , 一个类只能继承自另一个类 , 不能从多个类继承 。 但是 , 一个类可以是实现多个interface , 例如 :

//实现了两个interface
class Student implements Person , Hello {
	...
} 

#接口继承

接口之间的继承使用extends , 相当于扩展了接口的方法 :

interface Hello {
	void hello() ;
}

interface Person extends Hello {
	void run() ;
	String setName() ;
}

此时 , Person接口继承自Hello接口 , 因此 , Person接口现在实际上有3个抽象方法签名 ,其中一个来自继承的Hello接口 ;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值