面向对象高级——接口的基本概念和对象的多态性

接口

需要掌握接口的定义格式及使用
掌握接口与抽象类的关系
具体内容:
接口是Java中最重要的概念,接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。
如果一个类中完全是由全局常量(static final声明)和抽象方法组成,就可以将其定义成一个接口。
接口的定义格式:
interface 接口名称{
全局常量;
抽象方法;
}
interface A{		// 定义接口A
	public static final String AUTHOR = "刘勋" ;	// 全局常量
	public abstract void print() ;	// 抽象方法
	public abstract String getInfo() ;	// 抽象方法
}
对于接口来讲,因为在其定义的时候已经定义了其组成就是全局常量和抽象方法,所以,在开发中往往可以简化其定义
interface A{		// 定义接口A
	String AUTHOR = "刘勋" ;	// 全局常量
	void print() ;	// 抽象方法
	String getInfo() ;	// 抽象方法
}
以上两种定义方式是完全一样的,没有任何的区别。

实现接口
与抽象类一样,接口的使用也必须通过子类,子类通过implements关键字实现接口。
实现格式:
class 子类 implements 接口A,接口B{

}
接口的使用中也必须有子类,子类必须覆写全部的抽象方法,implements关键字实现,一个子类可以实现多个接口。如果子类不是抽象类的话,肯定要覆写接口中的全部抽象方法。
interface A{		// 定义接口A
	public String AUTHOR = "刘勋" ;	// 全局常量
	public void print() ;	// 抽象方法
	public String getInfo() ;	// 抽象方法
}
interface B{	// 定义接口B
	public void say() ;	// 定义抽象方法
}
class X implements A,B{	// X类同时实现A和B两个接口
	public void say(){
		System.out.println("Hello World!!!") ;
	}
	public String getInfo(){
		return "HELLO" ;
	}
	public void print(){
		System.out.println("作者:" + AUTHOR) ;
	}
};
public class InterfaceDemo03{
	public static void main(String args[]){
		X x = new X() ;	// 实例化子类对象
		x.say() ;
		x.print() ;
	}
};
接口的实现
以上程序中,一个子类同时实现了两个接口,这样在子类中就必须同时覆写完两个接口中的全部抽象方法。

继承抽象类实现接口:
一个子类可以同时继承抽象类和实现接口。格式如下:
class 子类 extends 抽象类 implements 接口A,接口B,...{}

interface A{		// 定义接口A
	public String AUTHOR = "刘勋" ;	// 全局常量
	public void print() ;	// 抽象方法
	public String getInfo() ;	// 抽象方法
}
abstract class B{	// 定义抽象类B
	public abstract void say() ;	// 定义抽象方法
}
class X extends B implements A{	// X类线继承B类,再实现A接口
	public void say(){
		System.out.println("Hello World!!!") ;
	}
	public String getInfo(){
		return "HELLO" ;
	}
	public void print(){
		System.out.println("作者:" + AUTHOR) ;
	}
};
public class InterfaceDemo04{
	public static void main(String args[]){
		X x = new X() ;	// 实例化子类对象
		x.say() ;
		x.print() ;
	}
};
在使用中,一个抽象类可以实现一个接口,那么对于抽象类的子类则就必须同时覆写接口和抽象类中定义的所有抽象方法。
interface A{		// 定义接口A
	public String AUTHOR = "李兴华" ;	// 全局常量
	public void print() ;	// 抽象方法
	public String getInfo() ;	// 抽象方法
}
abstract class B implements A{	// 定义抽象类B,实现接口A
	public abstract void say() ;	// 定义抽象方法
}
class X extends B{	// X类线继承B类
	public void say(){
		System.out.println("Hello World!!!") ;
	}
	public String getInfo(){
		return "HELLO" ;
	}
	public void print(){
		System.out.println("作者:" + AUTHOR) ;
	}
};
public class InterfaceDemo05{
	public static void main(String args[]){
		X x = new X() ;	// 实例化子类对象
		x.say() ;
		x.print() ;
	}
};
接口的继承
一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承。
格式:
interface 子接口 extends 父接口A, 父接口B, ...{}

interface A{		// 定义接口A
	public String AUTHOR = "刘勋" ;	// 全局常量
	public void printA() ;	// 抽象方法
}
interface B{
	public void printB() ;
}
interface C extends A,B{
	public void printC() ;
}
class X implements C{	// X类线继承B类
	public void printA(){
		System.out.println("A、Hello World!!!") ;
	}
	public void printB(){
		System.out.println("B、Hello JAVA") ;
	}
	public void printC(){
		System.out.println("C、Hello LX") ;
	}
};
public class InterfaceDemo06{
	public static void main(String args[]){
		X x = new X() ;	// 实例化子类对象
		x.printA() ;
		x.printB() ;
		x.printC() ;
	}
};

接口的总结:
1、只是阐述了接口的基本概念,而实际的应用并没有阐述。
2、接口是一个特殊的类,只包含全局常量和抽象方法。
接口中的抽象方法可以不加入abstract而抽象类中的抽象方法必须有abstract关键字声明。
3、一个类只能继承一个父类,但是可以同时实现多个接口。
4、一个接口可以同时继承多个接口,以实现接口的多继承。
5、接口和抽象类一样,都必须依靠子类。
6、一个抽象类可以实现多个接口,但是一个接口;不能继承一个抽象类。

对象的多态性

多态性:多态性在面向对象中是一个重要的概念,在JAVA中面向对象主要有以下两种主要体现:
方法的重载和覆盖。
对象的多态性。
对象多态性主要应用在抽象类和接口上。
对象的多态性主要分为以下两种类型:
向上转型:子类对象——>父类对象。对于向上转型,程序会自动完成,格式:
对象向上转型:父类 父类对象 = 子类实例;
向下转型:父类对象——>子类对象。对于向下转型,必须明确的指明要转型的子类类型,格式:
对象向下转型:子类 子类对象 = (子类)父类实例
class A{					// 定义类A
	public void fun1(){		// 定义fun1()方法
		System.out.println("A --> public void fun1(){}") ;
	}
	public void fun2(){
		this.fun1() ;		// 调用fun1()方法
	}
};
class B extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("B --> public void fun1(){}") ;
	}
	public void fun3(){
		System.out.println("B --> public void fun3(){}") ;
	}
};
public class PolDemo01{
	public static void main(String asrgs[]){
		B b = new B() ;		// 实例化子类对象
		A a = b ;			// 向上转型关系
		a.fun1() ;			// 此方法被子类覆写过
//		a.fun3() ;        //错误:子类向上转型后,是无法调用子类拓展的方法或属性的
	}
};


对于以上的程序,是通过其子类进行父类对象的实例化操作的,则如果调用的方法被子类覆写过,则肯定调用被覆写的方法。
注意点:转型之后,因为操作的是父类对象,所以是无法找到在子类中定义的新方法。
将父类对象变为子类对象成为向下转型,向下转型需要采用强制的手段。
class A{					// 定义类A
	public void fun1(){		// 定义fun1()方法
		System.out.println("A --> public void fun1(){}") ;
	}
	public void fun2(){
		this.fun1() ;		// 调用fun1()方法
	}
};
class B extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("B --> public void fun1(){}") ;
	}
	public void fun3(){
		System.out.println("B --> public void fun3(){}") ;
	}
};
public class PolDemo02{
	public static void main(String asrgs[]){
		A a = new B() ;			// 向上转型关系
		B b = (B)a ;		// 发生了向下转型关系
		b.fun1() ;
		b.fun2() ;
		b.fun3() ;
	}
};

在类B中存在三个方法,所以全部可以进行调用。
但是,在进行对象向下转型操作时必须注意一点:
class A{					// 定义类A
	public void fun1(){		// 定义fun1()方法
		System.out.println("A --> public void fun1(){}") ;
	}
	public void fun2(){
		this.fun1() ;		// 调用fun1()方法
	}
};
class B extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("B --> public void fun1(){}") ;
	}
	public void fun3(){
		System.out.println("B --> public void fun3(){}") ;
	}
};
public class PolDemo03{
	public static void main(String asrgs[]){
		A a = new A() ;			// 实例化了一个父类对象
		B b = (B)a ;		// 发生了向下转型关系
		b.fun1() ;
		b.fun2() ;
		b.fun3() ;
	}
};

以上异常是第二大出现的异常,此异常出现是在对象转型的时候经常发生的,如果两个没有关系的对象发生了转换关系,则肯定会出现此异常。
也就是说,如果要想产生对象的向下转型,则肯定必须先产生一个向上的转型关系。A a = new B(); 建立关系。
对象多态性的应用:
要求:设计一个方法,此方法可以接收A类的任意子类对象,并调用方法。
实现一:不使用对象的多态性完成。使用重载完成。
class A{					// 定义类A
	public void fun1(){		// 定义fun1()方法
		System.out.println("A --> public void fun1(){}") ;
	}
	public void fun2(){
		this.fun1() ;		// 调用fun1()方法
	}
};
class B extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("B --> public void fun1(){}") ;
	}
	public void fun3(){
		System.out.println("B --> public void fun3(){}") ;
	}
};
class C extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("C --> public void fun1(){}") ;
	}
	public void fun5(){
		System.out.println("C --> public void fun5(){}") ;
	}
};
public class PolDemo04{
	public static void main(String asrgs[]){
		fun(new B()) ;	// 传递B的实例
		fun(new C()) ;	// 传递B的实例
	}
	public static void fun(B b){
		b.fun1() ;		// 调用覆写父类中的fun1()方法
	}
	public static void fun(C c){
		c.fun1() ;		// 调用覆写父类中的fun1()方法
	}
};

如果按照以上思路,每增加一个子类,则fun方法就必须重载一次,当子类非常多时 就会无比繁琐。
此时,为了解决这个问题,就可以使用对象的多态性完成操作。
class A{					// 定义类A
	public void fun1(){		// 定义fun1()方法
		System.out.println("A --> public void fun1(){}") ;
	}
	public void fun2(){
		this.fun1() ;		// 调用fun1()方法
	}
};
class B extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("B --> public void fun1(){}") ;
	}
	public void fun3(){
		System.out.println("B --> public void fun3(){}") ;
	}
};
class C extends A{
	public void fun1(){		// 此方法被子类覆写了
		System.out.println("C --> public void fun1(){}") ;
	}
	public void fun5(){
		System.out.println("C --> public void fun5(){}") ;
	}
};
public class PolDemo05{
	public static void main(String asrgs[]){
		fun(new B()) ;	// 传递B的实例
		fun(new C()) ;	// 传递B的实例
	}
	public static void fun(A a){
		a.fun1() ;		// 调用覆写父类中的fun1()方法
	}
};

如果采用以上的方式,不管有多少子类,代码都可以轻易的完成。

多态性总结:
1、对象多态性的概念
向上转型:自动完成。
向下转型:强制。发生向下转型关系之前必须先发生向上转型的关系。
2、对象多态性可以解决方法接收参数的问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值