Java中抽象类与接口
抽象类
抽象类:抽象、笼统、模糊、看不懂、不具体。
抽象类特点:
- 方法只有声明没有实现,该方法就是抽象方法,需要被abstract修饰。
- 抽象类的方法必须定义在抽象类中,该类必须也被abstract修饰。
- 抽象类不可以被实例化。为什么?因为调用抽象方法没有意义。
- 抽象类必须由其子类覆盖了所有抽象方法后,该子类才可以实例化,否则这个子类还是抽象类。
问题:
抽象类有构造函数吗?
答:有构造函数,用于给子类对象初始化。
抽象类可以不定义抽象方法吗?
答:可以的,但是很少见,目的就是不让该类创建对象。AWT的适配器对象就是这种类。通常这个类中的方法有方法体,但是却没有内容。
如下:
abstract class Demo
{
void show1()
{};
void show2()
{};
}
抽象关键字不可以和哪些关键字共存?
答:
- private 关键字不可以跟 abstrac 共存,因为子类不能访问父类的私有函数,所以抽象类中的抽象函数不能被覆盖,所以私有不能跟抽象关键字共存。
- static 关键不行。
- final 关键字不行,因为 final 修饰的方法不可以被覆盖。
抽象类跟一般类异同点:
相同点:
- 抽象类和一般类都是用来描述事物的,都在类内部定义了成员。
不同点:
- 一般类有足够的信息描述事物。
- 抽象类描述事物的信息有可能不足。
- 一般类中不能定义抽象方法,只能定义非抽象方法。
- 抽象类中可以定义抽象方法,也可以定义非抽象方法。
- 一般类可以被实例化。
- 抽象类不可以被实例化。
抽象类一定是个父类?
- 是的,因为需要子类覆盖其方法后才可以对子类实例化。
抽象类简单例子:
/*
雇员实例:
需求:公司中程序员有姓名,工号,薪水,工作内容。
项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
对给出需求进行数据建模。
分析:
在这个问题领域中,先找出涉及的对象。
通过名词提炼法。
程序员:
属性:姓名,工号,薪水。
行为:工作。
经理:
属性:姓名,工号,薪水,奖金。
行为:工作。
*/
abstract class Employee
{
private String name;
private String number;
int salary;
abstract void work();
void setInformation(String name,String number,int salary)
{
this.name=name;
this.number=number;
this.salary=salary;
}
void getInformation()
{
System.out.println("name="+name+" number="+number+" salary="+salary);
}
}
class Programmer extends Employee
{
void work()
{
System.out.println("work Programmer...");
}
}
class Manager extends Employee
{
private int bonus;
void work()
{
System.out.println("work Manager...");
}
void setInformation(String name,String number,int salary,int bonus)
{
super.setInformation(name,number,salary);
this.bonus=bonus;
}
void getInformation()
{
super.getInformation();
System.out.println("bonus="+bonus);
}
}
class AbstractTest
{
public static void main(String[] args)
{
Programmer p=new Programmer();
p.getInformation();
p.work();
Manager m=new Manager();
m.getInformation();
m.work();
System.out.println("Hello World!");
}
}
接口
当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是接口interface。
定义接口使用的关键字不是class,而是interface。
对于接口当中常见的成员,而且这些成员都是有固定的修饰符:
- 全局常量:public static final
- 抽象方法:public abstract
例子如下:
interface Demo
{
int ID=7;
public static final int NUM=4;
public abstract void show1();
public abstract void show2();
}
class DemoImple implements /*实现关键字*/Demo
{
public void show1()
{}
public void show2()
{}
}
class InterfaceDemo
{
public static void main(String[] args)
{
Demo.ID=8;
System.out.println(Demo.num);
}
}
如果我在接口中定义int ID=7,程序会自动帮我加上关键字public static final 所以执行上述程序会报错:
由此可以得出结论,接口中的成员都是公共权限。
类与类之间是直接继承关系,类与接口之间是实现关系。接口不可以实例化,只能有实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化。否则,这个子类就是一个抽象类。java中不直接支持多继承机制,因为多继承会出现调用的不确定性。所以java中将多继承机制进行了改良,在java中变成了多实现。接口的出现避免了单继承的局限性,一个类可以实现多个接口,一个类在继承一个类的同时而且可以实现多个接口。接口与接口之间是继承关系,而且接口可以实现多继承关系,因为接口中没有方法体,所以不会出现调用的不确定性。
接口的特点:
- 接口是对外暴露的规则。
- 接口是程序的功能扩展。
- 接口的出现降低耦合性。
- 接口可以用来多实现。
- 类与接口之间是多实现关系,而且类可以继承一个类的同时实现多个接口。
- 接口与接口之间可以有继承和多继承关系。
抽象类和接口的异同点:
相同点:
- 都是不断向上抽取来的。
不同点:
- 抽象类需要被继承,而且只能单继承。
- 接口需要被实现,而且可以多实现。
- 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
- 接口中只能定义抽象方法,必须由子类去实现。
- 抽象类的继承是 is-a 关系,在定义该体系的基本共性内容,如果继承过程中 ,仅仅是覆盖了父类中的方法,则为 is-a 关系。
- 接口的实现是 like-a 关系,在定义体系额外功能。如果有新增的方法,则为 like-a 关系。
接口的例子:
interface USB//暴露的规则
{
public void open();
public void close();
}
class IntefaceDemo2
{
public static void main(String[] args)
{
useUSB(new Upan());//功能扩展了
useUSB(new Mouse());//功能扩展了
System.out.println("Hello World!");
}
//使用规则
public static void useUSB(USB u)
{
u.open();
u.close();
}
}
//一年后..................
//实现规则
class Upan implements USB
{
public void open()
{
System.out.println("Upan open");
}
public void close()
{
System.out.println("Upan close");
}
}
class Mouse implements USB
{
public void open()
{
System.out.println("Mouse open");
}
public void close()
{
System.out.println("Mouse close");
}
}