一.什么是抽象类?
标准化的说法就是——不能实例化的类,定义类的时候需要使用到abstract修饰符声明。
一般会涉及到继承的知识点。
就比如说,我定义出“三角形”“正方形”的类,它们都有共同的成员变量“边长”,有共同的方法“面积”“周长”,此时为了提高代码的复用率,这里我们将这些共同的特性抽取出来,创建一个新的类“Shape”,让“三角形”类,“正方形”类去继承“Shape”。此时,Shape就相当于是一个“抽象类”。因为Shape 形状,当我们看到这个词的时候我们能具体形象地说出这个形状到底是什么吗?
就像宠物,看到宠物这个词,有人想到猫,有人想到狗等等等等,我们没办法确定它到底是哪一种。又更何况在这些类里面定义的方法,”breath“ ”Cure"等等等等,不同的“对象”,都具有不同的呼吸方式,治疗方式。
所以在这些“泛指的”“有共性功能名字的”这些类,我们往往不对它具体实例化,也就是说,使它的方法体为空,不对它进行具体化对象
public abstract class Animal{
Animal animal=new animal();
//Animal就是一个抽象类,所以在这里我们一般不对它进行具体实例化,也就是上面那一行代码;
public abstract void breath(){}
//大括号里面不填写任何代码
}
在以上的代码段里,我们可以发现,当我们这么去写的时候,似乎多了一个“abstract”,那么接下来就来详细说说,抽象类要注意什么吧!
二.使用抽象类要注意什么?
1.格式:
/*[访问修饰符] <abstract> class <类名>{
[成员变量声明]
[方法定义]
}*/
//如下
public abstract class Shape{
//方法体
}
2.抽象方法:
(1)抽象方法里面不需要方法体:(在这里要注意“方法体为空”和“没有方法体”的区别)
- 没有方法体是指”{}“都没有
- 方法体为空是指”{}“里面没有任何的代码
- 抽象方法一般在子类中才会被实现
(2)抽象方法格式:
/*[访问修饰符] <abstract> 返回类型 方法名(参数列表);*/
public abstract double getArea();
public abstract double getPerimeter();
(3)抽象方法不能被private、final或static修饰:
- private——设置为私有的方法,外部无法进行方法,也实现不了“方法重写”
- final——要在子类中实现该方法,一旦被final修饰,就“冻结”了
- static——即便没有创建对象,也能通过类名来访问,从而就是在子类访问了一个没有方法体的方法,何谈实现?
(4)一般出现抽象方法的类,一定要定义为抽象类(抽象类和抽象方法是充分不必要条件)
(5)抽象类里面可以没有抽象方法,也可以有其他的非抽象的成员方法,构造方法,成员变量等等
如图所示:
(6)继承父类的子类,必须全部实现父类中的抽象方法,否则该子类应该声明为abstract类型
(7)抽象类的引用:
抽象类无法具体实例化对象,但是能够通过父类句柄=子类对象的方法,来实现子类对象的引用
public abstract class Father{
//声明为了抽象类
public abstract void drunk();
//创建一个抽象方法
}
class Son extends Father{
public void drunk(){
System.out.println("千杯不醉");
}//实现了父类中的抽象方法
}
class Test{
public static void main (String args[]){
Son s=new Son();
Father father=s;//父类引用子类对象
father.drunk();
}
}
三.接口(interface)是什么?
简单来说就是抽象类的一个特例,接口里面所有的方法都是抽象方法。
接口是一种行为功能的抽象;
同时,接口里只包含静态常量和抽象方法
四.使用接口要注意什么?
(1)声明接口的关键词:interface
(2)接口的定义格式:
/*
[权限修饰符] interface 接口名 [extends 父接口列表]{
//静态常量和抽象方法
[权限修饰符]————public和缺省
}*/
public interface Runner {
int Personid=1;
[public abstract] void start();
[public abstract] void end();
//在[[public abstract]]里面,表示:
//在接口里,对于方法的定义声明,我们可以省略public abstract
//同时,接口中的常量默认是公共的、静态的和最终的
//因此在声明时一般不需要用public、static、final
}
(3)接口与接口间是继承与被继承的关系,类与接口间是实现和被实现的关系;因此对于类使用接口,格式如下:
[访问修饰符][类型修饰符] class 类名 implements 接口名1,接口名2...{
}
ps:
- 一个子类只能有一个父类,但是可以有多个接口(多重继承)
- 子类在实现接口的时候,通常使用implements关键字,并要实现接口里的所有方法,就如同继承抽象类的时候。若无法实现所有的方法,应该声明为abstract类
(4)接口的使用:
- 声明接口变量
- 接口回调
五.自问:回顾了以上的问题,是否能够跟之前所学的内容搭建起来?
联系到继承的知识点。