Java之抽象类(Abstract Class)与抽象方法(Abstract Method)

抽象类(Abstract Class)

抽象类
        在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
        抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
       由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
        父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法
        我们这样定义抽象类:
Employee.java
public abstract class Employee {
    private String name;
    private String address;
    private int number;

    public Employee(String name, String address, int number) {
        System.out.println("构造一个雇员");
        this.name = name;
        this.address = address;
        this.number = number;
    }

    public void oneAddress() {
        System.out.println("名字为:" + this.name + ",地址为:" + this.address);
    }

    public void testMethod() {
        System.out.println("这是抽象类中的一个测试方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}

        上述抽象类中构造一个Employee对象,给出了一个someOne()方法,剩下的都是get和set方法,与普通类构造没太大区别。由于抽象类不能被不能直接实例化,所以我们通过构造其子类来操作,下面是其子类代码:

InheritanceEmployee.java

public class InheritanceEmployee extends Employee{
    public InheritanceEmployee(String name, String address, int number) {
        super(name, address, number);
    }

    public void oneAddress(){
        System.out.println("你的名字是:" + getName());
        System.out.println("你的地址是:" + getAddress());
        System.out.println("你的数字是:" + getNumber());
    }
}

        调用方法:

AbstractTest.java

public class AbstractTest {
    public static void main(String[] args) {
        // 通过子类实例化抽象类
        Employee employee = new InheritanceEmployee("小明", "北京", 10010110);
             employee.oneAddress();

        //调用抽象类中的测试方法
        employee.testMethod();
    }
}

        运行结果:

构造一个雇员
你的名字是:小明
你的地址是:北京
你的数字是:10010110
这是抽象类中的一个测试方法

Process finished with exit code 0

抽象方法

        如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
        Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

        抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

AbstractA.java

public abstract class AbstractA {
    private int a;

    public abstract void testA();

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

class SubclassB extends AbstractA {
    @Override
    public void testA() {
        System.out.println("这是抽象父类中的方法");
    }
}

        在抽象类中的方法只能定义,不能包含方法体。下面是调用方法:

ClassTest.java

public class ClassTest {
    public static void main(String []args){
        AbstractA abstractA = new SubclassB();
        abstractA.testA();
    }
}
        运行结果:

这是抽象父类中的方法


Process finished with exit code 0

相关习题

        1. 定义一个抽象的"Role"类,有姓名,年龄,性别等成员变量。
        1)要求尽可能隐藏所有变量(能够私有就私有,能够保护就不要公有),再通过getXXX()和setXXX()方法对各变量进行读写。具有一个抽象的play()方法,该方法不返回任何值,同时至少定义两个构造方法。Role类中要体现出this的几种用法。
        2)从Role类派生出一个"Employee"类,该类具有Role类的所有成员(构造方法除外),并扩展salary成员变量,同时增加一个静态成员变量“职工编号(ID)”。同样要有至少两个构造方法,要体现出this和super的几种用法,还要求覆盖play()方法,并提供一个final sing()方法。

        3)"Manager"类继承"Employee"类,有一个final成员变量"vehicle",在main()方法中制造Manager和Employee对象,并测试这些对象的方法。

PracticeOne.java

abstract class Role {
    private String name;
    private int age;
    private String sex;

    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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public abstract void play(); // 抽象方法

    public Role() {
        System.out.println("这是抽象类Role中蛋疼的方法");
    }

    public Role(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

class EmployeeOne extends Role {
    private double salary;
    private static String ID;

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public static String getID() {
        return ID;
    }

    public static void setID(String iD) {
        ID = iD;
    }

    public EmployeeOne() {
        System.out.println("这是EmployeeOne中蛋疼的方法");
    }

    public EmployeeOne(String name, int age, String sex, double salary, String ID) {
        super(name, age, sex);
        this.salary = salary;
        this.ID = ID;
    }

    @Override
    public void play() {
        // 重写抽象类中的play()方法
        System.out.println("员工编号:" + this.getID());

    }

    final void employeeInfo() {
        System.out.println("员工姓名:" + this.getName() + "员工性别:" + this.getSex() + "员工年龄:" + this.getAge() + "员工工资:" + this.getSalary());
    }
}


class Manager extends EmployeeOne {
    final String vehicle;

    public Manager(String name, int age, String sex, double salary, String ID, String vehicle) {
        super(name, age, sex, salary, ID);
        this.vehicle = "保时捷";
    }
}

public class PracticeOne {
    public static void main(String[] args) {
        // 构造EmployeeOne
        EmployeeOne employeeOne = new EmployeeOne("张三", 18, "", 5000, "123456");
        employeeOne.play();
        employeeOne.employeeInfo();
        // 构造Manager
        Manager manager = new Manager("李四", 20, "", 4500, "123457", "");
        manager.play();
        manager.employeeInfo();
        System.out.println("座驾是:" + manager.vehicle);
    }
}
        运行结果:

员工编号:123456
员工姓名:张三员工性别:男员工年龄:18员工工资:5000.0
员工编号:123457
员工姓名:李四员工性别:男员工年龄:20员工工资:4500.0
座驾是:保时捷

Process finished with exit code 0


        2. 编写一个Java应用程序,要求实现如下类之间的继承关系:
        1)编写一个抽象类Shape,该类具有两个属性:周长length和面积area,具有两个抽象的方法:计算周长getLength()和计算面积getArea()。
        2)编写非抽象类矩形Rectangle和圆形Circle继承类Shape。
        3)编写一个锥体类Cone,里面包含两个成员变量Shape类型的底面bottom和double类型的高height。
        4)定义一个公共的主类TestShape,包含一个静态的方法void compute(Shape e),通过该方法能够计算并输出一切图形的周长和面积;在主方法中调用compute方法,计算并输出某矩形和圆形的周长和面积,并测试锥体类Cone。

TestShape.java

interface ConstantValue {
    double PI = 3.1415926;  // 设置定值PI
}

abstract class Shape {
    double length;
    double area;

    abstract double getLength(); // 构造虚方法
    abstract double getArea(); // 构造虚方法
}

class Circle extends Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    double getLength() {
        length = 2 * ConstantValue.PI * radius;
        return length;
    }

    @Override
    double getArea() {
        area = ConstantValue.PI * radius * radius;
        return area;
    }
}

class Rectangle extends Shape{
    double width,height;
    
    Rectangle(double width,double height){
        this.width = width;
        this.height = height;
    }

    @Override
    double getLength() {
        length = (width + height) * 2;
        return length;
    }
    
    @Override
    double getArea() {
        area = width * height;
        return area;
    }
}

class Cone {
    Shape bottom;
    double height;

    public Cone(Shape bottom, double height) {
        super();
        this.bottom = bottom;
        this.height = height;
    }

    double getVolume() {
        return bottom.getArea() * height / 3;
    }
}

public class TestShape {
    public static void compute(Shape shape){
        System.out.println(shape.getClass());
        System.out.println("周长为:" + shape.getLength());
        System.out.println("面积为:" + shape.getArea());
    }
    public static void main(String []args){
        Circle circle = new Circle(5);
        Rectangle rectangle = new Rectangle(3,5);
        System.out.println("创建一个底面为圆形的椎体");
        Cone cone = new Cone(circle,10);
        compute(circle);
        System.out.println("体积为:" + cone.getVolume());
        System.out.println("------------这是华丽的分割线-------------");
        System.out.println("创建一个底面为矩形的椎体");
        cone = new Cone(rectangle,10);
        compute(rectangle);
        System.out.println("体积为:" + cone.getVolume());
    }
}
        运行结果:

创建一个底面为圆形的椎体
class Circle
周长为:31.415926
面积为:78.539815
体积为:261.7993833333333
------------这是华丽的分割线-------------
创建一个底面为矩形的椎体
class Rectangle
周长为:16.0
面积为:15.0
体积为:50.0

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_33567641/article/details/80986235