java抽象类和抽象方法

文章详细介绍了抽象方法和抽象类的概念,包括它们在编程中的作用和限制。抽象类是一种不能实例化的类,用于定义子类的规范,而抽象方法只有声明没有实现,需由子类来具体实现。文章还讨论了abstract与其他关键字如final、static和private的组合使用规则,强调了多态和继承在抽象类设计中的重要性。
摘要由CSDN通过智能技术生成



有的类就不适合创建出实例,比如Animal类,它的子类Dog类,Cat类都可以创建出实例,但是Animal类在现实中就是抽象的类别,更细的划分才有具体的对象。所以Animal类不适合创建出实例。
这种没办法创建出实例的类,我们应该设置为抽象类

大部分方法有具体的方法体,用来描述类的某种行为。但类里有的方法没办法写出具体的执行方式。比如Shape类的calPerimeter方法,只有Shape的子类triangle类或者rectangle类,才能写出具体的计算周长的算法。Shape类没有确定图形的形状,只是知道需要提供计算周长的方法,但具体的执行语句没办法写。所以,Shape类只能提供calPerimeter方法的签名,不能提供具体的方法体。
这种只能提供方法头,没办法提供方法体的方法,就是抽象方法

抽象类可以用有得有失来形容,多了定义抽象方法的能力,失去了创建对象实例的能力



抽象方法

抽象方法的定义

通用语法为: 访问修饰符 abstract 方法名(形参列表);
也就是只保留方法头,把方法体去掉,连{}都不要。抽象方法必须使用abstract关键字修饰
注意:public void test(){} 这种是方法体为空的普通方法,不是抽象方法,虽然{}里面什么都没有,但是它保留了花括号本身。



抽象类

抽象类的定义

用abstract标记的类就是抽象类。抽象类无法创建实例(不管有没有抽象方法),只是为子类定义一个共同的规范,用来实现多态
抽象类可以没有抽象方法,但有抽象方法的类只能是抽象类。抽象类的抽象方法可以是自身定义的,也可以是继承自父类或者来自接口。
抽象类的成员没有任何限制,5类成员(成员变量、方法、构造器、初始化块、内部类)都可以包含。抽象类虽然不能创建实例,但是需要拥有构造器。抽象类构造器的目的是为了被子类调用

抽象类与具体子类

如果一个类继承了抽象父类,子类想要被定义为普通类,就必须实现继承到的所有抽象方法(来自直接抽象父类或者间接抽象父类)。如果子类没有实现抽象父类的所有抽象方法,那它本身只能被定义为抽象类

抽象类的作用

抽象类虽然不能用于创建实例,但它设定了多个子类的通用模板,或者说定义一组子类共同的协议。子类总体上保留了抽象类的行为方式,同时可以在其基础上扩展和改造。
很多方法在抽象类的层次上是没办法写出具体实现的,那就定义为抽象方法,让具体的子类根据自身情况去实现方法体
抽象父类也可以提供一个通用算法,通用算法需要使用某个抽象方法的结果。比如SpeedMeter类的周长计算方法只能是抽象方法,但它的计算速度的算法可以写出通用的算法,算法内部需要使用计算周长方法的返回值,等具体的子类实现了计算周长方法后,这个通用算法就可以得到具体结果。
用SpeedMeter抽象类举例:

public abstract class SpeedMeter {
    private double turnRate;

    public SpeedMeter() {
    }

    public SpeedMeter(double turnRate) {
        this.turnRate = turnRate;
    }
	// 计算周长的算法目前只能是抽象方法,交给具体的子类继承
    public abstract double calGirth();

    public double getTurnRate() {
        return turnRate;
    }
	
    public void setTurnRate(double turnRate) {
        this.turnRate = turnRate;
    }
	
	// 可以写出计算速度的通用算法,该算法利用了计算周长的抽象方法
    public double getSpeed() {
        return turnRate * calGirth();
    }
}

class CarSpeedMeter extends SpeedMeter{
    private double radius;

    public CarSpeedMeter(double radius, double turnRate) {
        super(turnRate);
        this.radius = radius;
    }
	
	// 子类实现了计算周长的具体方法,继承的计算速度的通用算法就能得到具体结果了
    public double calGirth() {
        return 2 * Math.PI * radius;
    }

    public static void main(String[] args) {
        CarSpeedMeter car = new CarSpeedMeter(3, 15);
        System.out.println(car.calGirth());
        System.out.println(car.getSpeed());
    }
}


abstract与其他关键字

abstract与final

abstract修饰的类或者方法,必须被子类继承和重写才有意义,而final修饰的类或者方法,就不能被继承和重写。所以,abstract与final修饰符不能同时使用

abstract与static

类方法不能定义为抽象方法,因为父类的类方法只能被继承不能被重写,无法重写就没有必要定义为abstract。所以,static和abstract不能同时修饰某个方法
但是,abstract和static可以同时修饰内部类,表示该内部类是属于外部类的抽象类,表示它需要被子类继承后才有价值。

abstract与private

private修饰的方法表示只在类内部有效,子类根本无法继承私有方法。所以private修饰的方法本身就隐式含有final。所以private与abstract也不能共同修饰方法。

abstract与其他成员

abstract不能用于修饰变量(成员变量和局部变量都不行)。abstract也不能用于修饰构造器,抽象类的构造器不能用abstract标记,因为构造器不能被继承,所以没有设置为abstract的必要。抽象类的构造器内部可以有代码逻辑,但只能被子类调用,不能用于创建抽象父类的实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值