引入:
在文章 11.面向对象的三大特征的最后案例中,父类Animal类的cure()方法,目的就是让子类去重写它,但是函数体中的代码毫无意义,不写又会报错(定义一个标准的函数需要有函数体)。那怎样才能不写函数体呢?下面我们来解决这个问题
public void cure{
}
一、抽象方法:
如果一个方法,不需要实现体(函数内容),就可以声明抽象方法
1. 抽象方法:没有方法体的方法。java中使用abstract关键字声明的方法就是抽象方法。
2. 书写格式:
访问修饰符 abstract 返回值类型 方法名称(参数列表);
抽象方法必须定义在抽象类中。
public abstract class Animal{
public abstract void cure();
}
抽象类中不一定有抽象方法!!!
如果一个类继承了抽象类,就必须实现该类的抽象方法!!!
如果一定不实现,则将这个子类继续声明抽象类。
//抽象类中不一定有抽象方法
public class Animal {
// 100
private int health;
public int getHealth() {//普通方法
return health;
}
public void setHealth(int health) {//普通方法
this.health = health;
}}
// 如果一个类继承了抽象类,就必须实现该类的抽象方法
public class QQ extends Animial{
@override
public void cure(){
}
}
//如果一定不实现,则将这个子类继续声明抽象类。
public abstract class QQ extends Animial{
}
3. 抽象类:
被abstract关键字修饰的类。
public abstract class Animal{
}
二、接口:
接口,本质是特殊的类,特殊抽象类
接口中所有方法都是没有实现的(抽象方法)。
在jdk8之前:
接口中的所有属性和方法,默认都是public的!!!即便是你没有使用public关键字修饰。
java中使用interface关键字来定义接口
java中,接口可以多实现。
package com.openlab.day13.test02;
public interface MyInterface {
// 所有方法都是没有实现的(抽象方法),jdk8之前
public void say();
int sum(int x, int y);
public void sayHello();
}
package com.openlab.day13.test02;
public interface MyInterface02 {
void show();
}
接口的实现使用implements关键字实现接口
子类一旦实现了接口,必须要实现接口所有的抽象方法,
如果不想实现,则必须将该子类声明为抽象类。
package com.openlab.day13.test;
import com.openlab.day13.test02.MyInterface;
import com.openlab.day13.test02.MyInterface02;
public class Test02 implements MyInterface, MyInterface02 {
@Override
public void say() {
System.out.println("test02实现了say方法");
}
@Override
public int sum(int x, int y) {
return x + y;
}
@Override
public void sayHello() {
System.out.println("test02实现了sayhello方法");
}
@Override
public void show() {
System.out.println("子类的show方法");
}
}
package com.openlab.day13.test;
import com.openlab.day13.test02.MyInterface;
import com.openlab.day13.test02.MyInterface02;
public class Test {
public static void main(String[] args) {
MyInterface mi = new Test02();
mi.say();
mi.sayHell();
System.out.println(mi.sum(10, 20));
}
}
接口也无法直接实例化,必须使用子类,以多态的形式完成实例化。
注意:接口可以多实现!!
jdk8的接口新特性:
允许接口存在默认方法和静态方法,非抽象方法
package com.openlab.day13.test02;
public interface MyInterface02 {
void show();
// 定义一个默认方法方法
// 该方法主要的目的就是等待子类继承
public default void test01() {
System.out.println("定义在接口的方法");
}
// 定义一个静态方法方法
//相当于把接口当作工具类使用
public static int add(int a, int b) {
return a + b;
}
}
package com.openlab.day13.test;
import com.openlab.day13.test02.MyInterface;
import com.openlab.day13.test02.MyInterface02;
public class Test {
public static void main(String[] args) {
MyInterface02 mm = new Test02();
mm.test01();
}
}
接口与抽象类的区别(jdk8之前):
1 相同点 :
都位于继承的顶端, 用于被其他实现或继承 ;
都不能实例化;
都包含抽象方法,其子类都必须覆写这些抽象方法;
2. 区别 :
抽象类为部分方法提供实现, 避免子类重复实现这些方法 , 提供代码重用性 ; 接口只能包含抽象方
法;
一个类只能继承一个直接父类( 可能是抽象类 ), 却可以实现多个接口 ;( 接口弥补了 Java的单继承)
3. 二者的选用 :
优先选用接口, 尽量少用抽象类 ;
需要定义子类的行为, 又要为子类提供共性功能时才选用抽象类