1 什么是抽象类
举例:大家都知道,Java是面向对象的,而对象又是根据类去关联的。我们创建一个动物类,并在这个类中创建动物对象,但是当提到动物类时,你并不知道我说的是什么动物,只有看到具体的动物,你才知道了这是什么动物,所以动物指的是一个抽象的事务并不具体,所以我们不应该在动物类中给出具体实现,而是给出一个声明即可。(抽象就是从多个事务中将共性的,本质的内容抽取出来)
问题1:以上说法抽象类和普通类有什么区别呢,普通类也可以实现上述要求。
看到有篇博主写的比较通俗,拿来借鉴下:Java——为什么要有抽象类的概念?_奔跑的狮子a的博客-CSDN博客_为什么要有抽象类
定义一个动物类:
public class Animal { //创建一个动物类
private String name;
private Integer age;
public void cry(){ //因为动物会叫,此处定义一个“叫”方法
System.out.println("我要怎么叫呢"); //因为动物有很多种,而且我们这边定义的是一个常规类,我们并不知道动物要怎么叫
}
}
定义两个具体动物继承类实现
public class Cat extends Animal{ //猫类继承了动物类
@Override
public void cry() { //实现了cry方法
// super.cry();
System.out.println("我是小猫 喵喵喵");
}
}
public class Dog extends Animal{ //动物狗继承了动物类
@Override
public void cry() { //实现了里面的方法
// super.cry();
System.out.println("我是小狗 汪汪汪");
}
}
发现:虽然狗类和毛类都继承了动物类,但是动物类中的方法体并没有什么作用。因为具体的实现都有其独特的行为特征。
结论:这就是父类方法的不确定性。所以用抽象类把父类设计的抽象,以至于它都没有具体的示例。
当父类的方法不能够确定时,可以用abstract关键字修饰该方法,被abstract修饰的方法是抽象方法,被abstract修饰的类是抽象类。
程序修改如下:
public abstract class Animal { //创建一个动物类
private String name;
private Integer age;
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("我是小狗 汪汪汪");
}
}
2 接口和抽象类区别
3 什么是接口
在java中,一个类只能继承一个父类,但是一个类的实现包含多种多样的功能,仅仅通过继承一个类是不能实现用户需求的,所以引入了接口这个概念。我们可以通过实现多个接口,来丰富我们的类。
注意:
注意:
1、使用 interface 定义一个接口 接口中的方法一定是抽象方法, 因此可以省略abstract
2、接口中的方法一定是 public,因此可以省略 public
3、在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例. 接口不能单独被实例化
4、接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).
如果现在有一个接口,3个实现类,如果现在需要向接口中加一个方法,那么这3个实现类都需要改动。但是需求只要改动其中的两个实现类就可以了,那么我们可以再定义一个抽象类去实现这个接口,在抽象类中新增需要改动的方法,然后其他两个实现类实现这个这个抽象类就好了,或者使用 Java 8 中的新特性,在接口中新增默认方法或者静态方法。
例如:
接口A:
public interface A {
public void fun();
}
三个实现:AA、BB、CC
public class AA implements A{
@Override
public void fun() {
}
}
public class BB implements A{
@Override
public void fun() {
}
}
public class CC implements A{
@Override
public void fun() {
}
}
此时如果在接口A中新加入一种方法,那么3个实现类势必都要改动。
public interface A {
public void fun();
public void cry();
}
如果不想改动3个实现类,只想将有需要的实现类改动(BB、CC)。可以定义一个抽象类,将需要用到的方法定义在抽象类中。此时不需要改动原先接口了。
public abstract class Animal {
public abstract void cry(); //新需要的方法
}
让BB、CC这个两个实现类实现这个抽象类,
public class BB extends Animal implements A {
@Override
public void fun() {
}
@Override
public void cry() {
}
}
public class CC extends Animal implements A {
@Override
public void fun() {
}
@Override
public void cry() {
}
}
此时 就可以很直观的展现接口和抽象类的用法。