目录
[(4)抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰](#(4)抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰)
[(5)抽象方法不能是 private 的](#(5)抽象方法不能是 private 的)
(7)抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
一.抽象类
对于抽象类来说,抽象类就和他的名字一样,抽象!
至于怎么个抽象法,举个例子 :图形Shape,他并不特指哪一种形状,并不确切的描述某一对象。他可以是三角形,四边形,圆形。
一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
我们理解了之后,就可以来学习咯!
1.什么是抽象类
抽象类是用**
abstract
** 修饰的类,它不能被直接实例化 。关键字abstract
- 抽象类可以包含:
- 抽象方法(没有方法体的方法)。
- 普通方法(有具体实现的方法)。
- 成员变量(字段)。
- 构造方法。
定义语法:
java
abstract class AbstractClass {
protected int val; //成员变量
abstract void abstractMethod(); // 抽象方法
void concreteMethod() {
System.out.println("普通方法");
}
}
2.抽象类特点
(1)抽象类不能直接实例化对象
只能通过其子类来实例化对象。
(2)可以包含抽象方法和具体方法
抽象方法没有方法体,由子类实现。
具体方法是有实现代码的方法,可以直接被子类继承或覆盖。
java
abstract class Animal{
private String name;
private int age;
public Animal(String name,int age){
this.age=age;
this.name=name;
System.out.println(name+"今年"+age+"岁");
}
abstract void sound();//抽象方法没有方法体
public void methodA(){//具体方法是有实现代码的方法,可以直接被子类继承或覆盖。
System.out.println("这是方法A");
}
}
(3)可以有构造方法
尽管它不能直接被实例化 。构造方法在抽象类中存在的主要目的是让其子类可以通过调用这些构造方法来初始化从抽象类继承的成员变量或执行抽象类的初始化逻辑。
java
abstract class Animal{
private String name;
private int age;
public Animal(String name,int age){
this.age=age;
this.name=name;
System.out.println(name+"今年"+age+"岁");
}
abstract void sound();
}
class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
@Override
void sound() {
System.out.println("汪汪汪~");
}
}
public class Main {
public static void main(String[] args) {
Dog dog=new Dog("小七",2); //通过子类来实例化,并且在子类的构造方法调用父类的构造方法
}
}
(4)抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
java
abstract class Animal{
private String name;
private int age;
public Animal(String name,int age){
this.age=age;
this.name=name;
System.out.println(name+"今年"+age+"岁");
}
//抽象方法
abstract void sound();
public void methodA(){
System.out.println("这是方法A");
}
}
class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
//重写的方法
@Override
void sound() {
System.out.println("汪汪汪~");
}
}
如果把这一段代码删掉:
java
@Override
void sound() {
System.out.println("汪汪汪~");
}
则会报错:
我们来试着来将子类设置为抽象类:
可以看到子类没有报错提示了。但是子类又不能实例化对象了,因为被设置为抽象类了嘛。
(5)抽象方法不能是 private 的
修饰符的非法组合:"abstract"和"private"
这是因为这个抽象类被继承时,子类必须重写父类的抽象方法,当我们将该抽象方法写为private时,我们的子类就无法重写该抽象方法,也无法实现它,导致编译错误 ,因为private只能是同一类中才能够访问,所以抽象方法不能是private的。
(6)抽象方法不能被final和static修饰
修饰符的非法组合:"abstract"和"final"
修饰符的非法组合:"abstract"和"static"
因为抽象方法要被子类重写。被final和static修饰了子类就不能重写该抽象方法也无法实现了。
虽说是抽象方法不能被final和static和private修饰,但是抽象类里边的普通方法是可以被修饰的。
(7)抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
- 抽象类是用
abstract
修饰的类,但它可以不包含抽象方法。- 如果一个类是抽象的,即使没有抽象方法,它仍然不能被直接实例化。
- 这种抽象类的设计通常是为了提供一个基础类,用于子类的继承,可能包含一些已经实现的方法或共享的成员变量。
- 如果一个类中有任何一个方法被声明为
abstract
,那么这个类必须用abstract
修饰。- 否则,编译器会报错,因为没有
abstract
修饰的类默认是具体类(可以被实例化),但具体类不能包含未实现的方法。
(8)可以包含常量或实例变量
抽象类可以定义常量(
final
修饰)和普通的实例变量。
(9)成员变量不能被abstract修饰
在 Java 中,成员变量不能是抽象的 。这是因为 "抽象" 的概念是针对方法的,表示方法没有具体实现,要求子类去实现
为什么?
一方面,抽象方法表示没有实现的方法,依赖子类提供具体实现。而变量只是数据,没有"实现"的概念,因此不符合抽象的意义。
另一方面,成员变量在类加载时或对象创建时必须占用内存并初始化。如果变量是抽象的,无法确定其存储位置,也无法初始化。