在面向对象编程的过程中,我们往往会遇到很多复杂的对象,比如一个人的属性就可以有姓名,性别,身高,体重,年龄等等,如果我们将这些属性全部实现,费时费力,因为很多属性你可能根本用不上,这时候我们就需要将这些复杂的对象 抽象 成简单的对象,我们只需要我们需要的属性,而实现这种抽象的形式,就是 抽象类 和 接口。
抽象类
抽象类用 abstract 关键字修饰,抽象类中的抽象方法也用 abstract 修饰。抽象类和普通类一样,可以被继承,或者说,抽象类只有被继承才能发挥出它的用处,因为抽象类本身就起着一种规范的作用,子类可以有自己的方法,但是必须实现父类的方法,就像我们创建一个抽象的动物类,有吃饭,睡觉的方法,再创建一个狗类来继承这个动物类,那么这个狗会干什么我不管,但是它必须会吃饭睡觉,否则它就不是动物,同样的,在猫类,鼠类等必须这样做,这样就起到一个强制的作用,当一个项目很大的时候,如果不像这样规范的话,很容易就造成大量错误。
定义一个抽象类 Animal:
import java.math.BigDecimal;
public abstract class Animal {
//身高
protected BigDecimal height;
//体重
protected BigDecimal weight;
public abstract void eat();
public abstract void sleep();
public BigDecimal getHeight() {
return height;
}
public BigDecimal getWeight() {
return weight;
}
public void setHeight(BigDecimal height) {
this.height = height;
}
public void setWeight(BigDecimal weight) {
this.weight = weight;
}
}
可以看出,抽象方法是没有方法体的,并且抽象类不能被实例化,其他功能和普通类无区别。
创建一个 Dog 类继承 Animal 类:
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("----狗狗正在吃饭----");
}
@Override
public void sleep() {
System.out.println("----狗狗正在睡觉----");
}
public void digging(){
System.out.println("----狗狗正在挖土----");
}
}
?父类的抽象方法必须被重写。
调用这个子类:
public class Demo {
public static void main(String[] args){
Dog dog = new Dog();
dog.setHeight(BigDecimal.valueOf(0.4));
dog.setWeight(BigDecimal.valueOf(20));
dog.sleep();
dog.eat();
dog.digging();
System.out.println("狗狗身高:" + dog.getHeight() + "m");
System.out.println("狗狗体重:" + dog.getWeight() + "kg");
}
}
执行结果:
----狗狗正在睡觉----
----狗狗正在吃饭----
----狗狗正在挖土----
狗狗身高:0.4m
狗狗体重:20kg
?调用子类和调用普通类一样。
接口
接口相比于抽象类就更加强制性了,接口中可以有变量和方法,但是变量是默认被 public static final 修饰的,不管你写没写这几个关键字都会被这样修饰,因此接口中的变量从被赋值开始就是不可以更改的;而方法也是默认被 public abstract 修饰的,写其他修饰符会报错,所以接口中的方法只能是抽象的。因此,相比于抽象类,接口更偏向规范一些对象的共同属性,比如狗和汽车都会跑,但是不能写一个抽象类来当他们的父类,这时候就可以定义一个接口来实现跑这个方法。
定义一个动作接口:
public interface Action {
void run();
}
创建一个 Dog 类 和 Car 类实现这个接口:
public class Dog implements Action{
@Override
public void run() {
System.out.println("----狗狗正在跑----");
}
}
public class Car implements Action{
@Override
public void run() {
System.out.println("----汽车在跑诶----");
}
}
调用这两个类:
public class Demo {
public static void main(String[] args){
Dog dog = new Dog();
dog.run();
Car car = new Car();
car.run();
}
}
执行结果:
----狗狗正在跑----
----汽车在跑诶----
抽象类和接口区别:
- 一个类只能继承一个抽象类,但一个类可以实现多个接口。
- 抽象类中可以抽象方法,还可以进行具体实现,接口只能写抽象方法。
- 抽象类的变量可以被任何修饰符修饰,接口的变量只能是 public static final。
- 抽象类主要针对类进行抽象,接口主要针对类的功能或者说行为进行抽象。
- 抽象类中可以有静态代码块和方法,但接口不能有。
|