Java - 抽象与接口

1、抽象类

1.1抽象类

在Java语言中使用abstract class来定义抽象类。


1.1.1 抽象类的定义

public abstracat calss 类名{
}

1.2 抽象方法

public abstracat calss 类名{
	修饰符 数据类型 变量名;
	修饰符 abstract 返回值类型 方法名称(参数列表);
	修饰符 返回值类型 方法名称(参数列表){
			... ...
	}
}

1.3抽象类的特点

  • 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

  • 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

  • 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

  • 在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

  • 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

  • Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

  • 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号

  • 如果一个类包含抽象方法,那么该类必须是抽象类。

  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

1.3示例

public abstract class Human {
	
	public Human() { // 慕容博 伟大理想 恢复燕国
		super(); // 调用父类 Object 的构造方法
		System.out.println( "Human 构造方法执行" );
	}
	
	// 抽象方法: 被 abstract 修饰的、没有实现过程的方法
	public abstract void eat( String foodName ) ;
	
	public static void main( String[] args ) {
		// 抽象类不能被实例化
		// Human h = new Human(); // Cannot instantiate the type Human
	}

}

2、接口

2.1接口的声明

[public] interface 接口名称 [extends ···] {
       [public static final]数据类型 成员变量名 = 常量 ; // 声明变量
       [ public abstaract] 返回值类型 方法名称(参数列表);// 抽象方法
}

Eclipse 选中区域字母大小写切换 ctrl + shift + x / y
IDEA 选中区域字母大小写切换 ctrl + shift + y

2.2接口的特征

  • 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
  • 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
  • 接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

2.3接口的实现

  • 当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
  • 类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
...implements 接口名称 ...

2.4接口的访问权限

  • 接口的访问权限是public默认权限

2.5接口中的关键字

2.5.1关于接口下的default关键字

  • 从 JDK 1.8 开始允许在 接口中声明 默认方法 ( 是由 default 来修饰实例方法 )
    • default 修饰的方法内部可以通过 this 关键字 调用其他 default 修饰的方法【不要相互调用避免“死循环”,尽量单一调用】

2.5.2关于接口下的static关键字

  • 从 JDK 1.8 开始允许在接口中声明 static 方法 ( 非抽象的 )

2.5.3关于defaultstatic用法 ↓

public interface SwimAble {
	
	int ABC = 100 ; // public static final int ABC = 100 ;
	
	
	// 从 JDK 1.8 开始允许在 接口中声明 默认方法 ( 是由 default 来修饰实例方法 )
	public default void swim() {
		System.out.println( "在水里游" );
	}
	
	public default void sleep() {
		System.out.println( "在水里睡" );
		this.swim(); // default 修饰的方法内部可以通过 this 关键字 调用其他 default 修饰的方法【不要相互调用避免“死循环”,尽量单一调用】
	}
	
	// 从 JDK 1.8 开始允许在接口中声明 static 方法 ( 非抽象的 )
	public static void hello() {
		System.out.println( ABC );
	}
public class Fish implements SwimAble {
	
	
	// 重写 从 接口中继承的 默认方法 ( 由 default 修饰的实例方法 )
	@Override
	public void sleep() {
		// 如果需要调用接口中的 被覆盖的那个 默认方法,则需要通过 "接口名称.super.方法名( [参数] )"
		SwimAble.super.sleep();
	}

	public static void main(String[] args) {
		
		System.out.println( SwimAble.ABC );
		
		// SwimAble.swim(); // Cannot make a static reference to the non-static method swim() from the type SwimAble
		SwimAble.hello(); // 
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		SwimAble sa = new Fish();  //接口不能被实例化,所以只能指向实现此接口的类所对应的实例
		
		sa.swim();
		
		// Fish.hello(); // The method hello() is undefined for the type Fish
		
	}

2.6接口中的小问题

  • 如果一个类同时继承的父类和实现的接口拥有相同签名和返回类型时,当该类未重写方法,直接调用时,将会调用父类中的方法。

  • 如果一个类同时实现了两个拥有相同方法签名(相同的方法名、参数)、返回类型的default方法后,需要在类中重写default方法,否则编译器会因为不知道应该调用哪一个接口中的default方法而报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值