类和对象3

抽象类和抽象方法

当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么这些方法都有具体的方法体,但在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确地知道这些子类如何实现这些方法。


抽象方法(只有方法签名没有实现的方法)和抽象类必须使用abstract修饰来定义,有抽象方法的类只能定义成抽象类,抽象类里可以没有抽象方法

规则:

  1. 抽象类和抽象方法必须使用abstract修饰符来修饰,抽象方法不能有方法体

  2. 抽象类不能被实例化,我们不能用new关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能用来创建实例。

  3. 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要用于被其子类调用

  4. 含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。

定义抽象方法只需要在普通方法上增加abstract修饰符,并把普通方法的方法体(也就是方法后花括号的部分)全部去掉,并在方法后增加分号即可。

例如:
public abstract void book();

定义抽象类我们只需要在普通类上增加 abstract 修饰符即可。甚至一个普通类没有包含抽象方法的类,增加 abstract 修饰符后也将变成抽象类。
例如:
public abstract class SpeedMeter
{
    //转速
	private double turnRate;
	public SpeedMeter()
	{
		
	}
	//把返回车轮半径的方法定义成抽象方法
	public abstract double getRadius();
	public void setTurnRate(double turnRate)
	{
		this.turnRate = turnRate;
	}
	//定义计算速度的通用算法
	public double getSpeed()
	{
		//速度等于 车轮半径 *2 *PI *转速
		return java.lang.Math.PI * 2 *getRadius() * turnRate;
	}
	
}
public class CarSpeedMeter extends SpeedMeter
{
    public double getRadius()
    {
    	return 0.28;
    }
    public static void main(String[] args)
    {
    	CarSpeedMeter csm = new CarSpeedMeter();
    	csm.setTurnRate(15);
    	System.out.println(csm.getSpeed());
    }
}

当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。而final修饰的类不能继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。
关于abstract的小知识点:abstract不能用于修饰成员变量,不能用于修饰局部变量,即没有抽象变量、没有抽象,成员等说法;abstract也不能用于修饰构造器,没有抽象构造器,抽象类里定义的构造器只能是普通构造器。除此之外,当使用static修饰一个方法时,表明这个方法属于该类本身,即通过类就可以调用发方法,但如果该方法被定义成抽象方法,则导致通过该类来调用该方法时出现错误(调用了一个没有方法体的方法),因此static和abstract不能同时修饰某个方法,即没有所谓的类抽象方法。但它们也不是绝对互斥的,static和abstract虽然不能同时修饰某个方法,但它们可以同时修饰内部类。
抽象类的作用
抽象类不能够创建实例,只能当成父类来被继承。从语义的角度来看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出来一个抽象类,以这个抽象类作为其子类的模板,这样就避免了子类设计的随意性。

抽象类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,留给其子类去实现。

父类中可能包含需要调用其他系列方法的方法,这些被调方法既可以由父类实现,也可以由其子类实现。父类里提供的方法只是定义了一个通用算法,其实现也许并不完全由自身实现,而必须依赖于其子类的辅助。

归纳起来,抽象类可用“有得有失"4个字来描述。"得"是指抽象类多了一个能力:抽象类可以包含抽象方法,"失"指的是抽象类失去了一个能力:抽象类不能用于创建实例。

接口和抽象类的共同点和区别

共同点:1 接口和抽象类都是上层的抽象层
              2 都不能被实例化

              3 都能包含的抽象的方法,这些抽象的方法用于描述类具备的功能,但是不比提供具体实现

区别:

  1. 在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。

  2. 一个类只能继承一个直接父类;但是一个类可以实现多个接口

关于接口的知识本文不作介绍,大家有兴趣的可以自行查阅资料哦!

猜你喜欢

转载自blog.csdn.net/qq_41795427/article/details/79934418