抽象类(Abstract class):
抽象类概述:
抽象类是对根源的抽象(即对本质的抽象与其他类的本质不同)。
抽象类表示的是这个东西是什么。比如男人女人,,他们的抽象类就是人,所以继承也只能继承一个类(抽象类)(是人那就是人,不能是别的生物)
且如果有抽象的功能(吃,睡…),该类也必须是抽象类
抽象类的特点
- 抽象类和抽象方法都只能用abstract关键字修饰
- 抽象类中不一定只能有抽象方法,也可以没有,但有抽象类的一定是抽象方法
- 不能实例化
- 抽象类中的构造方法用于子类访问父类数据的初始化
- 抽象类的子类实现:
-
- 不重写抽象方法,该类定义为抽象类
-
- 重写所有的抽象方法 ,这时候子类就是一个具体的类
抽象类的成员特点(与接口区分)
- 成员变量 :可以是变量也可以是常量
- 构造方法:有
- 成员方法:有抽象方法也有非抽象方法
//父类
public abstract class Person {
private int a;
public Person(){
}
public abstract void show(); //抽象方法 没有方法体
public void demo(){ //非抽象方法
}
}
public class Student extends Person {
//具体子类就必须重写所有抽象方法
@Override
public void show() { //且变成非抽象方法
// TODO Auto-generated method stub
}
}
//抽象子类
public abstract class Teacher extends Person{
}
示例:
//父类
package com.st.basis.day09.abstarctdemo;
public abstract class Animal {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Animal(){ //无参构造
}
public Animal(String name, int age){ //带参构造
this.age = age;
this.name = name;
}
public abstract void eat(); //抽象方法
}
//子类
package com.st.basis.day09.abstarctdemo;
public class Dog extends Animal {
public Dog(){
super();
}
public Dog(String name, int age) {
super(name,age); //调用父类的构造方法
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
//测试类
package com.st.basis.day09.abstarctdemo;
public class AbstractDemo {
public static void main(String[] args) {
Animal dog1 = new Dog(); //多态创建对象dog1
dog1.eat();
dog1.setName("旺财");
dog1.setAge(1);
System.out.println(dog1.getName()+dog1.getAge());
System.out.println("--------");
Animal dog2 = new Dog("往往",10); //多态创建对象dog2
System.out.println(dog2.getName()+dog2.getAge());
}
}
接口(interface)
接口概述:
是对行为的抽象,里面包含供别人调用的方法和函数
抽象类把男人,女人抽象为人,定义他们是什么。而接口就定义他们做什么。
接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。
接口特点
- 接口用关键字interface表示
interface 接口名(){}
- 类实现接口:
class 类名 implements 接口名(){}
- 接口不能实例化(利用多态)
实现接口:
- 抽象类实现接口:意义不大,Dog应该是一个具体类,变成抽象还得再继承
public abstract class Dog implements Aniamal{
}
- 具体类实现接口:(很常见)
//接口
public interface Aniamal {
public abstract void eat();
}
//子类
public class Dog implements Aniamal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
//测试
public class InterfaceDemo {
public static void main(String[] args) {
Aniamal dog2 = new Dog();
dog2.eat();
}
}
接口中的成员特点:
- 接口中的成员变量默认为:public static final 变量(且无法修改)
- 方法指定为***public abstract***(也无法修改)
- 接口没有构造方法
- 方法则必须也只能是抽象方法
抽象类与接口区别:
- 成员变量区别具体看上面
- 关系区别:
类与类:继承关系,只能单继承,但可以多层继承
//Dog是类
//Aniamal,Aniamal2都是类
class Dog extends Aniamal{} //正确
class Dog extends Aniamal,Aniamal2{} //不支持
类与接口:实现关系。可以单实现,也可以多实现
//Dog是类
//Aniamal,Aniamal2都是接口
class Dog implements Aniamal{} //正确
class Dog implements Aniamal,Aniamal2{} //支持
class Dog extends implements Aniamal,Aniamal2 //支持
接口与接口:继承关系, 可以单继承,也可以多继承
//Dog,Aniamal,Aniamal2都是接口
interface Dog extends Aniamal{} //正确
interface Dog extends Aniamal,Aniamal2{} //支持
- 设计层面的区别:
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。