• 【java学习—九】抽象类和抽象方法(3)



    1. 相关概念

    抽象类:随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

    在这里插入图片描述

    2. 如何定义抽象方法和抽象类

    abstract关键字:
        (1)用 abstract 关键字来修饰一个类时,这个类叫做抽象类;
        (2)用 abstract关键字 来修饰一个方法时,该方法叫做抽象方法。

    抽象方法:
        只有方法的声明,没有方法的实现。以分号结束,如:

    	abstract int abstractMethod(int a);
    
    • 1

    注意:
    ①含有抽象方法的类必须被声明为抽象类
    抽象类不能被实例化。抽象类是用来作为父类被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类
    ③不能用 abstract 修饰属性、私有方法、构造器、静态方法、 final 的方法。

    3. 抽象类的作用

    举例:
    编程实现:父类为Animal类且为抽象类,子类有Dog、Fish、Bird类

    答:
    Animal类:

    package day09;
    
    public abstract class Animal {//定义父类Animal,因为类中含抽象方法,所以必须声明为抽象类
    	public abstract void test();//只要类中有一个抽象方法,类就必须是一个抽象类
    	
    	public abstract void move();
    }
    
    //定义子类:Dog、Fish、Bird(抽象类)
    //子类Dog
    class Dog extends Animal{
    	@Override
    	public void test() {
    		
    	}
    	
    	@Override
    	public void move() {
    		System.out.println("狗的移动方式是跑");
    		
    	}
    }
    
    //子类Fish
    class Fish extends Animal{
    	@Override
    	public void test() {
    		
    		
    	}
    	
    	@Override
    	public void move() {
    		System.out.println("鱼的移动方式是游");
    		
    	}
    }
    
    //抽象子类Bird:抽象类可以继承抽象类
    abstract class Bird extends Animal{//因为该类中没有重写test()方法,test()仍为抽象方法,所以Bird必须是抽象类
    	
    	@Override
    	public void move() {
    		System.out.println("鸟的移动方式是飞");
    	}
    		
    	public abstract void test();//只要类中有一个抽象方法,类就必须是一个抽象类
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    Test.java:

    package day09;
    
    public class Test {
    	public static void main(String[] args) {
    
    		Dog d = new Dog();
    		Fish f = new Fish();
    		//Bird b = new Bird();//抽象类不能被实例化
    		d.move();
    		f.move();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:

    在这里插入图片描述

    小结:抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提供具体实现的对象的类。

    4. 练习题

    4.1. 问题1

    问题情境:
        在航运公司系统中,Vehicle 类需要定义两个方法分别计算运输工具的燃料效率行驶距离
    问题:卡车 (Truck) 和驳船 (RiverBarge) 的燃料效率和行驶距离的计算方法完全不同。 Vehicle类不能提供计算方法,但子类可以。该如何实现?

    答案:

    // Vehicle 是一个抽象类,有两个抽象方法。
    public abstract class Vehicle{
    	public abstract double calcFuelEfficiency(); // 计算燃料效率的抽象方法
    	public abstract double calcTripDistance(); // 计算行驶距离的抽象方法
    }
    
    
    //Truck子类:
    public class Truck extends Vehicle{
    	public double calcFuelEfficiency( ) { 
    	// 写出计算卡车的燃料效率的具体方法 
    	}
    	
    	public double calcTripDistance( ) { 
    	// 写出计算卡车行驶距离的具体方法
    	 }
    }
    
    //RiverBarge子类:
    public class RiverBarge extends Vehicle{
    	public double calcFuelEfficiency( ) { 
    	// 写出计算驳船的燃料效率的具体方法
    	}
    	public double calcTripDistance( ) {
    	 // 写出计算驳船行驶距离的具体方法 
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    思考题:
    问题 1 :为什么抽象类不可以使用 final 关键字声明?
    答:(抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法 ,并提供方法体)
    问题 2 :一个抽象类中可以定义构造器吗?
    答:抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已;
        抽象类不能实例化,new 抽象类() 是非法的。

    4.2. 问题2

        编写一个 Employee 类,声明为抽象类,包含如下三个属性: name ,id , salary 。提供必要的构造器和抽象方法: work() 。对于 Manager类来说,他既是员工,还具有奖金 (bonus) 的属性。请使用继承的思想,设计 CommonEmployee 类和 Manager 类,要求类中提供必要的方法进行属性访问。

    答案:
    Employee类:

    package day09;
    
    //抽象类:Employee父类
    public abstract class Employee {
    	public Employee() {
    		
    	}
    	
    	int id;
    	String name;
    	double salary;
    	
    	public abstract void work();
    }
    
    //子类:普通员工
    class CommonEmployee extends Employee{
    	
    	public void setCommonEmployeeInfo(int id, String name, double salary) {
    		super.id = id;
    		super.name = name;
    		super.salary = salary;
    	}
    	
    	public void getCommonEmployeeInfo() {
    		System.out.println(super.id);
    		System.out.println(super.name);
    		System.out.println(super.salary);
    	}
    	
    	@Override
    	public void work() {
    		System.out.println("这是一个普通的员工");
    	}
    }
    
    
    //子类:领导
    class Manager extends Employee{
    	double bonus;
    	
    	public void setMangerInfo(int id, String name, double salary,double bonus) {
    		super.id = id;
    		super.name = name;
    		super.salary = salary;
    		this.bonus = bonus;
    	}
    	
    	public void getMangerInfo() {
    		System.out.println(super.id);
    		System.out.println(super.name);
    		System.out.println(super.salary);
    		System.out.println(this.bonus);
    	}
    	
    	@Override
    	public void work() {
    		System.out.println("这是领导");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    Test.java:

    package day09;
    
    public class Test {
    	public static void main(String[] args) {
    		//普通员工
    		CommonEmployee ce = new CommonEmployee();
    		ce.work();
    		ce.setCommonEmployeeInfo(123, "员工张", 6000.00);
    		ce.getCommonEmployeeInfo();
    		
    		System.out.println("---------------------------");
    
    		//领导
    		Manager me = new Manager();
    		me.work();
    		me.setMangerInfo(111, "领导李", 12000.00, 2000.00);
    		me.getMangerInfo();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    PostgreSQL 管理PG 的 4个 自制小脚本
    Github流出高质量高并发手册,看完面试手稳心不慌,吊打敢于提问高并发的面试官
    微信小程序原生<map>地图实现标记多个位置以及map 组件 callout 自定义气泡
    Java系列 - 反射
    基于axios 的二次封装
    Python自动化办公篇 - 104 - python实现邮件自动化 - 邮件发送
    JS计算代码执行时间三大方法
    2022年Java秋招面试必看的 | 微服务面试题
    Prism框架学习
    远场Far-Field beamforming与近场Near-Field beamforming有何关系
  • 原文地址:https://blog.csdn.net/weixin_44883789/article/details/134058097