抽象类
抽象类概述: 在java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
抽象类的练习
xpackage ch8;
public abstract class a_6_1Animal {
//下面的方法太具体了,如果以后需要有一个猫类。而猫类没有重写eat方法,就也会输出吃东西
/*public void eat() {
System.out.println("吃东西"); //方法体
}*/
//如何定义没有方法体的方法,如下 。在方法前面加一个abstract关键字,注意在这个类里面,即最上面,也要加abstract关键字
//这里定义了抽象方法和抽象类之后,测试类'a_6_2测试'里面的'new a_6_1Animal()'创建对象就会报错。因为a_6_1Animal不是具体的类就不能创建对象
public abstract void eat();
}
xxxxxxxxxx
package ch8;
public class a_6_2测试 {
public static void main(String[] args) {
//创建动物类对象(不是具体的类不能创建对象,如果下一行的a_6_1Animal是抽象类,则下一行会报错)
/*a_6_1Animal a = new a_6_1Animal();
a.eat();*/
//思考: 抽象类如何创建对象
}
}
抽象类的特点
抽象类特点总结: 抽象类不能直接使用,但可以参照多态的方式通过子类对象来实例化 (简单理解就是新建一个子类(使用继承),在子类里面重写父类的方法) 如果父类是抽象类,其继承的子类也会变成抽象类
第一个特点: 抽象类和抽象方法必须使用abstract关键字 第二个特点: 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类 第三个特点: 抽象类不能实例化(即不能为抽象类创建对象)。解决方法:参照多态的方式,通过给子类对象实例化,间接就给不能实例化的父类对象实例化了,这叫抽象类多态 第四个特点: 抽象类的子类要么重写抽象类中的所有抽象方法,要么这个抽象类的子类就会变成抽象类(或理解为这个抽象类的子类本身就是抽象类)
抽象类特点的练习
xxxxxxxxxx
package ch8;
//抽象类
public abstract class a_7_1Animal {
//抽象类里面可以有抽象方法
public abstract void eat(); //不给方法体的话,要加一个abstract关键字。上一行的类前面也需要加一个abstract关键字
//抽象类里面可以有非抽象方法
public void sleep() {
System.out.println("睡觉"); //这里有方法体,所以这个sleep不是抽象的哦
}
}
package ch8;
public class a_7_2测试 {
public static void main(String[] args) {
//a_7_1Animal a = new a_7_1Animal(); //a_7_1Animal是抽象类,这行创建不了对象。解决写法如下
//新建一个类为a_7_3Cat且为了叙述方便简称为猫类,在猫类里面继承动物类,在猫类里面重写动物类的eat方法
//在去测试类里面(也就是这里)以多态的形式创建对象(如下一行)
a_7_1Animal a = new a_7_3Cat();
a.eat();
a.sleep();
//就解决了
//原理: 虽然'a_7_1Animal'类是抽象的,但是'a_7_1Animal'类里面的方法被子类"a_7_3Cat"重写了
//所以此时给抽象类创建对象和使用抽象类里面的方法就不会报错
//归根结底就是多态的成员方法(简单理解就是方法)是编译看左边,运行看右边
}
}
xxxxxxxxxx
package ch8;
//继承动物类
public class a_7_3Cat extends a_7_1Animal {
//重写动物类的eat方法,上面那行的继承就不会报错了
public void eat() {
System.out.println("猫类中的重写方法-重写父类的eat()");
}
}
xxxxxxxxxx
package ch8;
//继承动物类(继承的动物类是抽象类,所以这里的a_7_4Dog也会报成抽象类)
public abstract class a_7_4Dog extends a_7_1Animal {
//如果下一行不重写父类的方法,这行就会报错。解决方法是在上一行加一个abstract关键字
}
抽象类的成员特点
成员变量: 1、可以是常量 2、也可以是变量
构造方法: 1、有构造方法,但是不能实例化 2、构造方法的作用是用于子类访问父类数据的初始化
成员方法: 1、抽象方法的作用是限定子类必须完成某些动作 2、非抽象方法的作用是提供代码的复用性
抽象类成员特点的练习
xxxxxxxxxx
package ch8;
//抽象类,研究抽象类可以包含哪些成员
public abstract class a_8_1Animal {
//成员变量
private int age = 20; //变量
private final String city = "北京"; //常量
//成员方法,非抽象方法
public void show() {
age = 40;
System.out.println(age);
//下面那行会报错,因为city被final修饰,此时的city是常量不能被重新赋值
//city = "上海";
System.out.println(city);
}
//成员方法,抽象方法
public abstract void eat();
//成员方法,无参构造方法
public a_8_1Animal() {
}
//成员方法,带参构造方法
public a_8_1Animal(int age) {
this.age = age;
}
}
x
package ch8;
public class a_8_2测试 {
public static void main(String[] args) {
a_8_1Animal a = new a_8_3Cat();
a.eat();
a.show();
}
}
xxxxxxxxxx
package ch8;
public class a_8_3Cat extends a_8_1Animal {
public void eat() {
System.out.println("猫类中的重写方法-重写父类的eat()");
}
}
猫和狗_抽象版类
需求: 请采用抽象类的思想实现猫和狗案例,并测试
思路:
一、定义动物类 1、成员变量: 姓名,年龄 2、构造方法: 无参,带参 3、成员方法: get和set方法,吃饭()的抽象方法
二、定义猫类,继承动物类 1、构造方法: 无参,带参 2、成员方法: 重写吃饭()
三、定义狗类,继承动物类 1、构造方法: 无参,带参 2、成员方法: 重写吃饭()
四、定义测试类,并测试
猫和狗_抽象版类的练习
x
package ch8;
//抽象类
public abstract class a_9_1Animal {
//成员变量
private String name;
private int age;
//带参构造方法
public a_9_1Animal(String name, int age) {
this.name = name;
this.age = age;
}
//无参构造方法
public a_9_1Animal() {
}
//get和set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//抽象方法
public abstract void eat();
}
xxxxxxxxxx
package ch8;
//继承动物类
public class a_9_2Cat extends a_9_1Animal {
//带参构造方法
public a_9_2Cat(String name, int age) {
super(name, age);
}
//无参构造方法
public a_9_2Cat() {
}
public void eat() {
System.out.println("猫类中的重写方法-重写父类的eat()");
}
}
xxxxxxxxxx
package ch8;
//继承动物类
public class a_9_3Dog extends a_9_1Animal {
//带参构造方法
public a_9_3Dog(String name, int age) {
super(name, age);
}
//无参构造方法
public a_9_3Dog() {
}
public void eat() {
System.out.println("狗类中的重写方法-重写父类的eat()");
}
}
xxxxxxxxxx
package ch8;
public class a_9_4测试 {
public static void main(String[] args) {
//创建对象,按照多态的方式
a_9_1Animal a = new a_9_2Cat();
a.setName("猫名1");
a.setAge(2);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("-----------------");
a = new a_9_2Cat("猫名2",4);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
}
}