目录
1.1 概述
在Java中,一个没有方法体的方法应该定义为抽象方法,,而类中如果有抽象方法,该类必须定义为抽象类
- 在Java语言中,定义方法时,以abstract修饰的方法只声明返回的数据类型、方法名和所需的参数,没有方法体,这样的方法就是抽象方法。
- 在一个类中,如果有某些方法不需要实现具体细节。或不能确定具体细节,则可以定义为抽象方法,包含抽象方法的类,称为抽象类。
抽象方法基本语法格式:
[修饰符] abstract <返回值类型> <方法名> ( [参数列表]);
说明:
抽象方法的声明必须使用abstrct关键字。例如:
public abstract void eat ();
抽象类基本语法格式:
[修饰符] abstract class <类名>
{
类
};
说明:
- 抽象类的声明必须使用abstrct关键字。例如:
public abstract class eat ();- 抽象类中可以不包含抽象方法。
- 抽象类中可以写普通方法。
- 抽象类不能被实例化。(不能创建对象)
- 抽象类的子类如果没有实现父类的所有抽象方法,同样也要定义为抽象类。
- 抽象方法必须在抽象类中。
例如:
public class AnimalTest {
public static void main(String[] args) {
// Animal a = new Animal(); //报错
// a.eat();
}
}
// class Animal {
// public void eat(){
// System.out.println("吃东西");
// }
// }
abstract class Animal {
public abstract void eat();
}
1.2 抽象类的特点
抽象类和抽象方法必须使用abstract 关键字修饰
- public abstract class 类名 {}
- public abstract void eat();
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化
- 抽象类如何实例化呢?参照多态的方式,通过子类对象实例化,这叫抽象类多态
抽象类的子类
- 要么重写抽象类中的所有抽象方法
- 要么是抽象类
例如:
public class AnimalTest {
public static void main(String[] args) {
// Animal a = new Animal();//报错
Animal a = new Cat();
a.eat();
a.sleep();
}
}
// 抽象类
abstract class Animal {
// 抽象方法
// public abstract void eat(); //注释之后不会报错
public abstract void eat();
public void sleep() {
System.out.println("睡觉");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
abstract class Dog extends Animal {
public abstract void eat();// 注释之后不会报错
}
结果:
1.3 抽象类的成员特点
- 成员变量:可以是变量,也可以是常量
- 构造方法:有构造方法,但是不能实例化。那么,构造方法的作用是什么呢?用于子类访问父类数据的初始化
- 成员方法
- 可以有描象方法:限定子类必须完成某些动作
- 也可以有非抽象方法:提高代码复用性
例如:
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();
a.show();
}
}
abstract class Animal {
private int age = 20;
private final String city = "北京";
// 抽象类不能实例化指的是不能直接实例化,但能通过多态的方式来实例化
// 构造方法的作用用于子类访问父类数据的初始化,在子类的构造方法中会来访问这个父类的构造方法,用于给数据初始化
public Animal() {
}
public Animal(int age) {
this.age = age;
}
public void show() {
age = 40;
System.out.println(age);
// city="上海"; //报错
System.out.println(city);
}
abstract void eat();
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
结果:
案例:
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Cat();
a.setName("梨花");
a.setAge(3);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("-----------");
a = new Cat("梨花", 3);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("============");
Animal b = new Dog();
b.setName("柴犬");
b.setAge(5);
System.out.println(b.getName() + "," + b.getAge());
b.eat();
System.out.println("-----------");
b = new Dog("柴犬", 5);
System.out.println(b.getName() + "," + b.getAge());
b.eat();
}
}
abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
abstract void eat();
}
class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
结果:
案例一
abstract class Person{
abstract void go();
}
class Teacher extends Person{
void go(){
System.out.println("老师教书");
}
}
class Student extends Person{
void go(){
System.out.println("学生学习");
}
}
public class Action {
public static void main(String[] args) {
Teacher t = new Teacher();
Student s = new Student();
t.go();
s.go();
}
}
运行结果:
案例二:错误代码演示
abstract class Person{
abstract void eat();
abstract void speak();
}
class Teacher extends Person{ //报错
void eat(){
System.out.println("老师教书");
}
}
public class Action {
public static void main(String[] args) {
Teacher t = new Teacher();
t.eat();
}
}
分析:Teacher不是抽象的, 并且未覆盖Person中的抽象方法speak()。