⭐️小剧场⭐️
关于抽象类,下面说法正确的有?(答案在结尾)
A.抽象类中一定包含抽象方法,有抽象方法的类一定是抽象类
B.抽象类中的静态方法可以抽象,但构造方法不行
C.抽象类某些情况下可以被实例化。
D.抽象类必须有构造方法
🌕抽象类全解析
🌴1.什么是抽象类?
我们平时学习的普通类,它的构造有普通成员变量、普通成员方法、静态成员变量和静态成员方法以及一些方法体内的局部变量。而抽象类中它还可以包含抽象方法。所以我们初步就知道了,具有抽象方法的类就是抽象类。为了表示抽象的概念,我们需要在类的前面加上abstract关键字,告诉别人我们这个方法是抽象方法
🌴2.什么是抽象方法?
首先我们要明白一点,什么叫做抽象?抽象当然就是无法具体的描绘写来或者实例出来。我们都知道方法都是有一对{},大括号里面的内容就是我们的方法体,既然我们的抽象方法是无法具体的写出来的,那肯定是没有方法体的,所以我们要知道,抽象方法是没有方法体的方法。为了告诉别人我们的方法是抽象方法,所以要在前面加上abstract关键字。书写的格式如下:
public abstract class animal {//定义一个抽象类 abstract void test();//定义一个抽象方法,没有方法体也没有{},直接以;结尾 }
🌴3.什么时候使用抽象类和抽象方法?
我们都知道,一个类,代表一类具有共同身份或者特征的群体或者事务。比如老师这个群体,她可以是一个类,有生日和姓名这个属性,每天老师需要休息,吃饭还要工作等,通过这样我们写出老师类
public class Teacher {//表示老师类 String name;//姓名 String birthday;//生日 public void sleep(){}//表示休息的行为 public void eat(){}//表示吃饭的行为 public void word(){}//表示工作的行为 }
这时,根据我们的需求,我们还需要一个学生类,那我们再分析学生有哪些属性和行为呢?首先学生同样也有姓名和生日这两个属性,而且还可以加上一个学号。行为也有休息吃饭和工作(学习当然也是工作)等行为。于是我们得到学生类
public class Student {//表示学生类 String name;//姓名 String birthday;//生日 int id;//学号 public void sleep(){}//表示休息的行为 public void eat(){}//表示吃饭的行为 public void word(){}//表示工作的行为 }
这时我们突然发现,老师类和学生类有着类似的属性和行为,在两个类中同时声明相同的,这不是代码冗余了嘛?这时我们聪明的人们就想到,我们能不能把它们共有的东西都抽出来,然后让具有这些属性和行为的类去继承得到,这样就不用复写这么多相同的代码了。于是抽象类应用而生
🔑:抽象类是将多个类中的具有的相似的或者共有的属性和方法抽取出来的一个类。通过继承抽象类来获得这些属性和方法,从而减少我们地代码量,提高我们写代码地效率。
因为老师和学生都有人,所以我们抽取出它们的共同属性和行为一个抽象类Person
public abstract class Person { String name;//姓名 String birthday;//生日 abstract void sleep();//表示休息的行为 abstract void eat();//表示吃饭的行为 abstract void word();//表示工作的行为 }
这时我们通过继承简化代码,去书写老师类和学生类
public class Teacher extends Person { @Override void sleep() { System.out.println("老师去教师宿舍休息"); } @Override void eat() { System.out.println("老师去老师饭堂吃饭"); } @Override void word() { System.out.println("老师认真教学"); } } public class Student extends Person { int id; @Override void sleep() { System.out.println("学生去学生宿舍休息"); } @Override void eat() { System.out.println("学生去学生饭堂吃饭"); } @Override void word() { System.out.println("学生认真听老师上课"); } }
注意事项:Person已经抽取了共同的属性name和birthday,所以我们继承以后不用再写学生需要补上学号的属性
🎃:抽象方法之所以不能有方法体,正是为了体现我们Java语言多态的特性,虽然老师和学生都有工作的方法行为,但工作的内容却不相同,一个是教书一个是上课。所以在抽象类中我们无法书写抽象方法的方法体,这也是抽象方法存在的意义。
🌴4.抽象类常考点归纳解析和易错点
🍋 1.抽象类不能实例化
前面我们已经提过,抽象类是抽调了几个类的相似属性和方法,它并不是指具体的某个类,当然不能实例化。而且想想名字,抽象抽象,抽象的东西当然不能实例咯。当然我们不能忘记,抽象类一般都是作为父类被继承,利用它父类的身份我们可以利用面向对象中的面向对象指向子类实例,当然这不属于实例化。这是抽象类最最最基本的性质,千万不能忘记!!利用上面Person类和Student演示如下
Person student = new Student();
🍋 2.抽象类中不一定包含抽象方法,有抽象方法的类必定是抽象类
🎃:这是很多人都容易犯错的点,正如开头我们所讲,抽象类只是在普通类的基础上可以加上抽象方法,也可以理解为普通类是抽象类的子集,所以即使没有抽象方法,你也是可以将类声明为抽象类的。同理,既然你的类中有了抽象方法,那就不可能是普通类了,就一定是抽象类了。希望大家好好理解。
🍋 3.构造方法和静态方法不能声明为抽象方法
🔑 :我们知道构造方法是我们在new对象时,用来给参数赋值的方法,抽象方法是没有方法体的而且也无法直接调用,如果给构造方法声明为抽象方法,那它就没有意义了,也无法使用了。对于静态方法,静态方法是无法重写的,它是可以通过类名直接调用的,既然不能重写,当然也不能声明成抽象方法,没有方法体的方法,被调用的话有什么意义呢?
🍋 4.抽象类必须得有构造方法
🌺:很多人想不明白,抽象类不能实例化,那为什么还要有构造方法呢?这就是面向对象的知识点不扎实的体现。我们已经提过,抽象类肯定是作为父类被子类继承,那么当我们子类在实例化的时候,会首先去调用父类的无参构造,如果没有,则需要去调用有参构造,否则程序会报错。所以抽象类的构造方法是为了给子类调用的
🍋 5.子类必须实现抽象类的所有抽象方法,除非子类也为抽象类
🌲:其实这非常好记,通过上面第二条结论和继承我们就可以明白。假设我们父类有五个抽象,当你子类继承后,也得到了这五条抽象方法,如果你只重写了1条,这时候编译器说了,不行!你这子类怎么还有四条抽象方法呢?我都说了有抽象方法的类必定是抽象类,除非你把子类声明抽象类,不然不给你通过,于是你老实的四条也重写了。举这个例子是方便大家记忆和理解透彻,所以当我们继承抽象类时,一般都得实现全部抽象方法。
🍋 5.小剧场解答
如果你认真观看了我这篇文章,现在回去很容易就能知道答案是D。在这我就不在讲解为啥了。