目录
抽象类
在面向对象概念中,所有的对象都是通过类来描绘的,但并不是所有的类都用来描述对象,如果一个类没有包含足够的信息来描绘一个具体的对象,这样的类就称为抽象类。我们也将包含抽象方法的类称为抽象类。
那么什么是抽象方法?什么是抽象类?又该去怎么定义呢?
例如下列代码:
//抽象类
abstract class Animal{
abstract void bark();//抽象方法
}
class Dog extends Animal{
@Override
void bark() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal{
@Override
void bark() {
System.out.println("喵喵喵");
}
}
抽象方法: 在上述代码中,Cat类和Dog类都继承了Animal类,狗和猫都会发出叫声,但是两个动物的叫声完全不同,因此没有必要在父类Animal中实现bark()方法,就算实现了,也没有任何的实际作用,因此可以将bark()设计成一个抽象方法。抽象方法不需要具体实现,只需定义出即可,具体实现在子类中进行重写。
抽象类:将包含抽象方法的类称为抽象类,在定义时需要使用abstract来修饰。抽象类也是类,内部也可以包含普通方法和属性,甚至可以包括构造方法。
抽象类的特性
1.抽象类不能直接实例化对象;
2.抽象方法不能以private定义,因为抽象方法需要在继承类中进行重写,private是私有属性,它所定义的方法只能在当前类中使用;
3.抽象方法也不能被final、static修饰,因为抽象方法在子类中需要被重写;
4.抽象类必须被继承,并且在被继承后需要在子类中重写父类中的抽象方法,否则子类也是抽象类,也需要用abstract来修饰;
5.抽象类中不一定包含抽象方法,但包含抽象方法的类一定是抽象类;
6.抽象类中可以有构造方法,供子类创建对象时来初始化父类的成员变量.
抽象类的作用
创建抽象类和抽象方法非常有必要,因为它们可以使类的抽象性明确起来,并告诉用户和编译器打算怎么使用它们。抽象类还是很有用的重构工具,因为它们使得我们可以很容易的将公共方法沿着继承层次结构向上移动。
使用抽象类也相当于多了一重编译器的校验,可以使我们尽早的发现代码中的问题。例如:当一件事情需要由子类来完成时,却不小心使用了父类,使用普通类编译器是不会报错的,但是如果父类是抽象类此时就会报错,让我们尽早发现错误。
接口
接口就是公共行为的规范标准,在实现时只要符合规定,就可以通用,例如:USB接口,电源插口这类。
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
接口的定义格式与类的定义格式基本一致,将class关键字换成interface关键字,就定义了一个接口
定义方式如下:
public interface IOperation {
public abstract void method1();
public void method2();
abstract void method3();
void method4();
//上述四个定义方式都是抽象类方法,推荐最后一种定义方式,代码简洁.
}
接口的使用
接口不能直接来使用,需要有一个“实现类”来“实现该接口”,实现接口中所有的抽象方法.
class 类名 implements 接口名 {
//....
}
子类与父类之间是extends继承关系,类与接口之间是implements实现关系.
接口的使用示例如下:
一个类实现一个接口
public interface IOperation {
void work();
}
class AddOperation implements IOperation{
@Override
public void work() {
System.out.println("增加操作");
}
}
class DelOperation implements IOperation{
@Override
public void work() {
System.out.println("删除操作");
}
}
class DisplayOperation implements IOperation{
@Override
public void work() {
System.out.println("显示操作");
}
}
一个类实现多个接口
在Java中,类和类之间是单继承的关系,即Java中不支持多继承,但是一个类可以实现多个接口.
public interface IFlying {
void fly();
}
interface IRunning{
void run();
}
interface ISleeping{
void sleep();
}
class Bird implements IFlying, IRunning, ISleeping{
@Override
public void fly() {
System.out.println("它在飞");
}
@Override
public void run() {
System.out.println("它在跑");
}
@Override
public void sleep() {
System.out.println("它在睡觉");
}
}
接口的使用特性
1.接口类型是一种引用类型,但不能直接new接口的对象;
2.接口中的每一个方法都是public的抽象方法,即接口中所有的方法都会被隐式地定义为public abstract;
3.接口中的方法不能在接口中实现,只能由实现接口的类来实现;
4.重写接口中的方法时,不能用default来修饰;
5.接口中可以含有变量,但是接口中的变量都会被隐式的定义为public static final类型;
6.接口中不能有静态的代码块和构造方法;
7.接口虽然不是类,但是接口编译后字节码文件后缀也是.class;
8.如果类中没有实现接口中的所有抽象方法,则类必须设定为抽象类.
抽象类和接口类的区别
相同点:
1.都是上层的抽象层;
2.都不能被实例化;
3.都能包含抽象的方法,这些抽象的方法用于描述类具备的功能,但不提供具体的实现.
不同点:
1.在抽象类中可以定义非抽象方法,从而避免在子类中重复写它们,这样可以提高代码的复用性,而接口中只能有抽象的方法;
2.一个类只能继承一个直接父类,但是一个类可以实现多个接口.