Java学习(五)抽象类和接口


一、抽象类

1.定义抽象类

(1)abstract关键字放在class前,指明该类是抽象类
(2)abstract关键字放在方法的返回类型前,指明该方法是抽象方法,抽象方法没有方法体,并以“;”结束;
(3)抽象方法和空方法是两个完全不同的概念:
   public abstract void call();//抽象方法,没有{}方法体;
   public void call(){} //空方法,有{}方法体,但没任何语句。()没有参数。

(4)包含抽象方法的类必须声明为抽象类。
如果一个类中有抽象方法,那它一定是抽象类。反之不成立,抽象类中不一定有抽象方法。(包含0或多个抽象方法)
(5)抽象类不能被实例化;
一个抽象类可以有多个抽象方法,也可以没有抽象方法,但即便没有抽象方法,也不能被实例化;
(6)抽象类可以直接定义,可以通过继承一个抽象类,也可以通过实现一个接口来定义。
(7)abstract和final不能同时修饰同一个类,因为abstract修饰的类只有被继承才有意义,而final修饰的类不能被继承。
(8)抽象类:“没有完全实现的类”。

2.使用抽象类

Animal.java:动物类,抽象类

public abstract class Animal{
	private String name;
	public Animal(){
	}
	public Animal(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
	//抽象方法
	public abstract void action();
	public abstract void call();
}

Horse.java:马类,继承于动物类

public class Horse extends Animal{
	public Horse(){
	}
	public Horse(String name){
		super(name);
	}
	//重写抽象方法
	public void action(){
		System.out.println(this.getName()+"四条腿奔跑");
	}
	public void call(){
		System.out.println(this.getName()+"长啸");	
	}
}

Bird.java:鸟类,继承于动物类

public class Bird extends Animal{
	public Bird(){
	}
	public Bird(String name){
		super(name);
	}
	//重写抽象方法
	public void action(){
		System.out.println(this.getName()+"翅膀飞");
	}
	public void call(){
		System.out.println(this.getName()+"叽喳叫");	
	}
}

AbstractDemo.java:测试

public class AbstractDemo{
    public static void main(String[] args){
	//不能实例化一个抽象类,但可以让抽象类变量指向其子类对象
	Animal a;
	a=new Horse("马儿");	
	a.action();
	a.call();
	a=new Bird("鸟儿");
	a.action();
	a.call();
    }
}

运行结果:
在这里插入图片描述

二、接口

接口定义了某一批类所需要遵守的公共行为规范,只规定这批类必须提供的某些方法,而不提供任何实现。
**接口是一种特殊的、完全没有实现的“类”,**与抽象类不同,接口中的所有方法都是抽象方法(Java 8以后,开始允许在接口中定义默认方法和类方法,默认方法用default修饰,类方法用static修饰),所有数据都是常量(final)。
java语言不支持多继承,因此采用接口来实现多继承。

1.定义接口

接口定义的语法如下:
[public] interface interfaceName [extends superInterface,]
{
[public] [static] [final] type constName=constValue;
[public] [abstract] returnType functionName(paramList);
}
接口的访问符可以是public或者默认,默认则为包权限。
接口中的数据都是public static final,因此这些修饰符可以不写。
接口中的方法都是public abstract,因此也可以不写。
一个接口可以继承多个父接口,但不能继承类。

2.使用接口

接口不能直接实例化,一个类可以实现一个或多个接口。
格式:[访问符] class 类名 implements 接口1,接口2…

一个类要实现接口时,应注意以下几个问题:
(1)在类的声明部分,用implements声明类要实现哪些接口。
(2)如果实现某接口的类不是抽象类,则该类必须实现接口中所有定义的方法
(3)一个类实现某接口时,必须使用完全相同的方法头(重写),如果实现了同名但参数不同的函数,则系统认为重载了此方法,而不是实现此抽象函数。
(4)接口的函数都是public,因此实现方法时,必须显示的使用public修饰符。

接口的优势主要在于:
类通过实现多个接口可以实现多重继承
能够抽象出不相关类之间的相似性,而没有强行形成类的继承关系。

3.接口的继承

接口的继承与类的继承不一样,接口完全支持多重继承,即一个接口可以有多个父接口。除此之外,接口的继承与类的继承相似:当一个接口继承父接口后,该接口将会获得父接口中定义的所有抽象方法、常量。
一个接口继承多个接口时,用extends关键字,多个接口间使用逗号“,”隔开。

InterfaceExtendsDemo.java:

interface InterfaceA{
    int a = 10;
    void testA();
}
interface InterfaceB{
    int b = 20;
    void testB();
}
interface InterfaceC extends InterfaceA,InterfaceB{
    int c = 30;
    void testC();
}
//实现第三个接口
public class InterfaceExtendsDemo implements InterfaceC{
    //实现三个抽象方法
    public void testA(){
	System.out.println("testA()方法");
    }
    public void testB(){
	System.out.println("testB()方法");
    }
    public void testC(){
	System.out.println("testC()方法");
    }
    //主函数
    public static void main(String[] args){
	InterfaceExtendsDemo ie = new InterfaceExtendsDemo();

	System.out.println(ie.a);
	System.out.println(ie.b);
	System.out.println(ie.c);

	ie.testA();
	ie.testB();
	ie.testC();
    }
}

InterfaceExtendsDemo1.java:

interface InterfaceA{
    int a = 10;
    void testA();
}
interface InterfaceB{
    int b = 20;
    void testB();
}
interface InterfaceC extends InterfaceA,InterfaceB{
    int c = 30;
    void testC();
}
//实现第三个接口
public class InterfaceExtendsDemo1 implements InterfaceC{
    //实现三个抽象方法
    public void testA(){
	System.out.println("testA()方法");
    }
    public void testB(){
	System.out.println("testB()方法");
    }
    public void testC(){
	System.out.println("testC()方法");
    }
    //主函数
    public static void main(String[] args){
	//使用InterfaceC接口可以直接访问a、b、c三个常量
	System.out.println(InterfaceC.a);
	System.out.println(InterfaceC.b);
	System.out.println(InterfaceC.c);
	//声明第三个接口变量,并指向其实现类的实例对象
	InterfaceC ic = new InterfaceExtendsDemo1();
	//调用接口中的方法
	ic.testA();
	ic.testB();
	ic.testC();
    }
}

两个文件中都是由第三个接口实现两个父接口,然后用一个类来实现第三个接口。
不同的是:
第一个文件中,直接定义了类的实例,然后用类的实例对象访问常量和方法
第二个文件中,直接用第三个接口访问常量,用第三个接口的实现类的对象访问三个方法。

4.接口和抽象类的相似性

相似性:
a.接口和抽象类中都可以包含抽象方法,实现接口或抽象类时必须实现这些抽象方法。
b.接口和抽象类都不能被实例化,需要被其他类实现或继承。
c.接口和抽象类的类型变量都可以指向其实现类或子类的实例对象。

5.接口和抽象类的区别

区别:
a.接口体现的是一种规范,而抽象类体现的是一种模板。
b.接口中的函数都是abstract,而抽象类可以定义带有方法体的不同方法。
c.一个类可以实现多个接口,而一个类只能继承一个抽象类。
d.接口与实现它的类不构成类的继承体系,即接口不是类体系的一部分
e.接口不包含构造方法,而抽象类可以包含构造方法,目的不是实例化对象,而是让其子类调用以便完成初始化。


三、例题

在这里插入图片描述

abstract class B1{
abstract int b1f();
public int infb2(){return 30;}
}
interface InfB1{  int infb1();  }
interface InfB2 extends InfB1{
	int infb2();
}
public class ExamB extends B1 implements InfB2{
	int b1f(){return 10;}
	public int infb1(){return 20;}
	public int infb2(){return 30;}
	public static void main(String args[]){
		ExamB examB=new ExamB();
		System.out.println(examB.infb1());//运行结果为20
		System.out.println(examB.infb2());//运行结果为30
	}
}

总结

接口体现的是一种规范和实现分离的设计哲学,充分利用接口能够降低程序各模块之间的耦合,从而提高系统的可扩展性以及可维护性。
基于这种原则,许多软件设计架构都倡导“面向接口”编程,而不是面向实现类编程,以便通过面向接口编程来降低程序之间的耦合。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君知燕云归

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值