抽象类
抽象类概述: 在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(); }xxxxxxxxxxpackage 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关键字 第二个特点: 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类 第三个特点: 抽象类不能实例化(即不能为抽象类创建对象)。解决方法:参照多态的方式,通过给子类对象实例化,间接就给不能实例化的父类对象实例化了,这叫抽象类多态 第四个特点: 抽象类的子类要么重写抽象类中的所有抽象方法,要么这个抽象类的子类就会变成抽象类(或理解为这个抽象类的子类本身就是抽象类)
抽象类特点的练习
xxxxxxxxxxpackage 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"重写了 //所以此时给抽象类创建对象和使用抽象类里面的方法就不会报错 //归根结底就是多态的成员方法(简单理解就是方法)是编译看左边,运行看右边 }}xxxxxxxxxxpackage ch8;
//继承动物类public class a_7_3Cat extends a_7_1Animal {
//重写动物类的eat方法,上面那行的继承就不会报错了 public void eat() { System.out.println("猫类中的重写方法-重写父类的eat()"); }}xxxxxxxxxxpackage ch8;
//继承动物类(继承的动物类是抽象类,所以这里的a_7_4Dog也会报成抽象类)public abstract class a_7_4Dog extends a_7_1Animal {//如果下一行不重写父类的方法,这行就会报错。解决方法是在上一行加一个abstract关键字 }
抽象类的成员特点
成员变量: 1、可以是常量 2、也可以是变量
构造方法: 1、有构造方法,但是不能实例化 2、构造方法的作用是用于子类访问父类数据的初始化
成员方法: 1、抽象方法的作用是限定子类必须完成某些动作 2、非抽象方法的作用是提供代码的复用性
抽象类成员特点的练习
xxxxxxxxxxpackage 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(); }}xxxxxxxxxxpackage 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();}xxxxxxxxxxpackage 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()"); }}xxxxxxxxxxpackage 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()"); }}xxxxxxxxxxpackage 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(); }}