接口和抽象

 抽象类

当定义一个类时,常常需要定义一些成员方法描述类的行为特征,但有时这些方法的实现方式是无法确定的。例如,前面在定义Animal类时, shout()方法用于描述动物的叫声,但是不同动物的叫声是不同的,因此在shout()方法中无法准确地描述动物的叫声。

针对上面描述的情况, Java提供了抽象方法来满足这种需求。抽象方法是使用abstract关键字修饰的成员方法,抽象方法在定义时不需要实现方法体。抽象方法的定义格式如下:

abstract 返回值类型 方法名称(参数);

当一个类包含了抽象方法,该类必须是抽象类。抽象类和抽象方法一样,必须使用abstract关键字进行修饰。

抽象类的定义格式如下:

abstract class 抽象类名称{
属性;
访问权限 返回值类型 方法名称(参数){                                //普通方法
return[返回值];
访问权限 abstract 返回值类型 抽象方法名称(参数);//抽象方法,无方法体
}

抽象类的定义规则如下。

(1)包含抽象方法的类必须是抽象类。

(2)抽象类和抽象方法都要使用abstract关键字声明。

(3)抽象方法只需声明而不需要实现。

(4)如果一个类继承了抽象类,那么该子类必须实现抽象类中的全部抽象方法。

//定义抽象类Animal
abstract class Animal {
	// 定义抽象方法shout()
	abstract void shout();
}

// 定义Dog类继承抽象类Animal
class Dog extends Animal {
	// 实现抽象方法shout()
	void shout() {
		System.out.println("汪汪……");
	}
}
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.shout();
	}
}

运行结果:汪汪……

使用abstract关键字修饰的抽象方法不能使用private修饰,因为抽象方法必须被子类实现,如果使用了private声明,则子类无法实现该方法。

 接口

如果一个抽象类的所有方法都是抽象的,则可以将这个类定义接口。接口是Java中最重要的概念之一。在JDK8中,接口中除了可以包括抽象方法外,还可以包括默认方法和静态方法(也叫类方法),默认方法使用default修饰,静态方法使用static修饰,且这两种方法都允许有方法体。

接口使用interface关键字声明,语法格式如下:

public interface 接口名 extends 接口1,接口2...{
public static final数据类型常量名=常量值;
public abstract返回值类型抽象方法名称(参数列表);
}

“extends接口1,接口2...”表示一个接口可以有多个父接口,父接口之间用逗号分隔。Java使用接口的目的是克服单继承的限制,因为一个类只能有一个父类,而一个接口可以同时继承多个父接口。接口中的变量默认使用“public static final”进行修饰,即全局常量。接口中定义的方法默认使用“public abstract”进行修饰,即抽象方法。如果接口声明为public,则接口中的常量和方法全部为public。

一个类可以在继承另一个类的同时实现多个接口,并且多个接口之间需要使用英文逗号(,)分隔。

定义接口的实现类,语法格式如下:

修饰符 class 类名 implements 接口1,接口2,…[

...

}
interface Animal {
	int ID = 1; // 定义全局常量
	String NAME = "牧羊犬";

	void shout(); // 定义抽象方法shout()

	static int getID() {
		return Animal.ID;
	}

	public void info(); // 定义抽象方法info()
}

interface Action {
	public void eat(); // 定义抽象方法eat ()
}

//定义Dog类实现Animal接口和Action接口
class Dog implements Animal, Action {
	// 重写Action接口中的抽象方法eat ()
	public void eat() {
		System.out.println("喜欢吃骨头");
	}

	// 重写Animal接口中的抽象方法shout()
	public void shout() {
		System.out.println("汪汪……");
	}

	// 重写Animal接口中的抽象方法info()
	public void info() {
		System.out.println("名称:" + NAME);
	}
}

public class Test {
	public static void main(String[] args) {
		System.out.println("编号" + Animal.getID());
		Dog dog = new Dog(); // 创建Dog类的实例对象
		dog.info();
		dog.shout(); // 调用Dog类中重写的shout()方法
		dog.eat();

	}
}

运行结果:

编号1
名称:牧羊犬
汪汪……
喜欢吃骨头

定义了一个Animal接口,在Animal接口中定义了全局常量ID和NAME,抽象方法shout()、info()和静态方法getID()。在Action接口中定义了一个抽象方法eat()。Dog类通过implements关键字实现了Animal接口和Action接口,并实现了这两个接口中的抽象方法。Animal接口名直接访问了Animal接口中的静态方法getID()。

Dog类的实例化对象可以访问接口中的常量、实现的接口方法和本类内部的方法,而接口中的静态方法则可以直接使用接口名调用。需要注意的是,接口的实现类,必须实现接口中的所有方法。

一个类既要实现接口,又要继承抽象类,则可以按照以下格式定义类。 

修饰符 class类名 extends 父类名 implements接口1,接口2,…   {
.......
}

 如修改后:

abstract class Action{
	public abstract  void eat(); // 定义抽象方法eat ()
}
class Dog extends Action implements Animal{


}

Dog类通过extends关键字继承了Action抽象类,同时通过implements实现了Animal接口。因为Animal接口和Action抽象类本身都有抽象方法,所以Dog类中必须重写Animal接口和Action 象类中的抽象方法。

在Java中,接口是不允许继承抽象类的,但是允许一个接口继承多个接口。

interface Animal {
	public String NAME = "牧羊犬";
	void info();
}
interface Color {
	public void black();
}
interface Action extends Animal, Color {
	void shout();
}
class Dog implements Action {
	public void shout() {
		System.out.println("汪汪……");
	}
	public void black() {
		System.out.println("黑色");
	}
	public void info() {
		System.out.println("名称:" + NAME);
	}
}
public class Test {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.info(); 
		dog.shout();
		dog.black(); 

	}
}

运行结果:

名称:牧羊犬
汪汪……
黑色

接口Action继承接口Animal和Color,这样接口Action中就同时拥有Animal接口中的info()方法和Color接口中的black()方法,以及本类中的shout()方法。定义了一个Dog类并实现了Action接口,这样Dog类就必须同时实现这3个抽象方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值