抽象类
在 Java 中所有的对象都是通过类来描述的,但并不是所有的类都是用来描述对象的,如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类。
当发现多个类中有共有的方法时,可以将他们抽象出来,例如,狗和狼都会叫这一行为,而且它们都属于犬科类,所以将这一行为抽象出来,定义犬科为抽象类。狗和狼均继承犬科类,并覆盖其方法。在子类中具体实现。
示例一:
package 抽象类;
abstract class 犬科{
abstract void 叫();//抽象函数,需要用abstract修饰,用分号结束。
}
class Dog extends 犬科{
void 叫(){
System.out.println("汪汪汪 ");
}
}
class Wolf extends 犬科{
void 叫(){
System.out.println("吼吼吼");
}
}
public class AbstractDemo1 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.叫();
Wolf wolf = new Wolf();
wolf.叫();
}
}
复制代码
1. 抽象类和抽象方法必须由abstract
关键字指定。抽象方法一定要定义在抽象类中。
2. 抽象类不可以创建实例(即不能 new 对象),原因:调用抽象方法没有意义。所以抽象类必须被继承。
3. 只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。否则该子类还是一个抽象类。
4. 任何子类必须重写父类中的所有抽象方法,否则声明自身为抽象类。
示例二:
`public abstract class Animal {
public abstract void cry();
}
public class Cat extends Animal{
@Override
public void cry() {
System.out.println("猫叫:喵喵...");
}
}
public class Dog extends Animal{
@Override
public void cry() {
System.out.println("狗叫:汪汪...");
}
}
public class Test {
public static void main(String[] args) {
Animal a1 = new Cat();
Animal a2 = new Dog()
a1.cry();
a2.cry();
}
}`
复制代码
关于抽象类和抽象方法的几个问题:
1.抽象类一定是一个父类?
是的,因为抽象类是不断抽取而来的。
2.抽象类是否有构造方法?
有,虽然抽象类不能给自己的对象初始化,但是可以给自己的子类对象初始化,
3.抽象类和一般类的异同点:
3.抽象类中是否可以不定义抽象方法?
可以的,此时的意义仅仅是不让该类创建对象。
4.抽象关键字abstract不可以和哪些关键字共存?
1)final 修饰的类不能有子类,而抽象类必须有子类。
2)private 私有的,也不能被覆盖
3)static 静态方法随着类的加载而加载。
接口
当一个抽象类中的方法全是抽象的时候,用interface
关键字定义,接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。
接口是抽象类的延伸,接口是隐式抽象的,当声明一个接口的时候,不必使用abstract
关键字。
interface Animal {
public void eat();
public void travel();
}
复制代码
接口的特点
1.接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类
2.子类必须覆盖接口中所有的抽象方法后,子类才可以实例化。
3.接口中不存在具体的实现的方法
4.接口没有构造方法。
5.接口中所有的方法必须是抽象方法。
6.变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称为常量
7.方法必须有固定的修饰符,public abstract ,所以接口中的成员都是公共的。
8.接口支持多继承。
示例一:
package 接口;
/*
* 定义一个接口,接口中可以有成员变量和方法
* 注意:
* 变量:变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称为常量
* 方法:方法必须有固定的修饰符,public abstract ,所以接口中的成员都是公共的。
*/
interface Demo{
public static final int NUM = 6;
public abstract void show1();
public abstract void show2();
/*
* 也可以写成此类型
* int NUM = 6;
* void show1();
* void show2();
*/
}
//类实现接口,并重写接口中的方法
public class DemoImpl implements Demo{
@Override
public void show1() {
}
@Override
public void show2() {
}
}
复制代码
注意事项:
接口中的方法都没有方法体,由子类来明确。接口可以多实现。
接口的出现避免了单继承的局限性;在 Java 中,类的多继承是不合法,但接口允许多继承。
在接口的多继承中extends
关键字只需要使用一次,在其后跟着继承接口。
父类中定义的事物的基本功能;接口中定义事物的扩展功能。
示例二:
interface interA{
void show1();
}
interface interAA{
void show11();
}
interface interB extends interA,interAA{//接口实现多继承
void show2();
}
class Test implements interB{
@Override
public void show1() {}
@Override
public void show11() {}
@Override
public void show2() {}
}
复制代码
接口与抽象类的区别
事件描述:
犬:假如按照功能分类:导盲犬,缉毒犬。。。
行为:吼叫();吃饭();
abstract class 犬{
public abstract void 吼叫();
public abstract void 吃饭();
}
abstract class 缉毒{
public abstract void 缉毒();
}
class 缉毒犬 extends 犬{
@Override
public void 吼叫() {
}
@Override
public void 吃饭() {
}
public void 缉毒(){
}
}
//其他的动物可能也会有缉毒功能,无法实现多继承,当犬是接口,缉毒也是接口时,可以多实现。但是类负责描述的是事物的基本功能,接口负责描述事物的扩展功能。所以,犬可以描述为类,缉毒可以描述为接口。
所以 以上代码改为:
abstract class 犬{
public abstract void 吼叫();
public abstract void 吃饭();
}
interface 缉毒{
public abstract void 缉毒();
}
class 缉毒犬 extends 犬 implements 缉毒{
@Override
public void 吼叫() { }
@Override
public void 吃饭() { }
public void 缉毒(){ }
}
复制代码
区别
抽象类是描述事物的基本功能,可以定义非抽象的方法;接口中的定义的方法是抽象的。
类与类之间是继承关系,类与接口是实现关系。
抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
抽象类中的成员变量可以是各种类型,而接口中的成员变量只能是 public static final
类型的。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
接口中不能含有静态代码块以及静态方法(用 static
修饰的方法),而抽象类可以有静态代码块和静态方法。
抽象类是自下而上来设计的,接口是自上而下设计的。
评论