抽象类的概述:
abstract:关键字,用于修饰类和方法
抽象方法:不同类的方法是相似,但是具体内容又不太一样,所以
我们只能抽取他的申明,没有具体的方法体,没有具体方法体的方法就是抽象方法。
抽象类:有抽象方法的类必须是抽象类
注意:一个类继承了抽象类需要重写他所有的抽象方法,否则这个类就得是抽象类
public class AbstractDemo01 {
}
abstract class Animal{
public abstract void eat();
public void run() {
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃屎");
}
}
抽象类的特点:
* 抽象方法只能放在抽象类中
* 抽象类和抽象方法必须要被abstract修饰
* 抽象类不能创建对象,(不能实例化)
* 抽象类可以有非抽象方法
* 抽象类和类的关系也是继承
* 一个类继承了抽象了要么继承了所有的抽象方法,要么他自己就是抽象类。
public class AbstractDemo02 {
public static void main(String[] args) {
//Animal02 an = new Animal02();//出错:抽象类不能创建对象(不能实例化)
Animal02 an = new Animal02() {
@Override
public void eat() {
// TODO Auto-generated method stub
}
};
}
}
abstract class Animal02{
public abstract void eat();
public void run() {
}
}
class Cat01 extends Animal02{
@Override
public void eat() {
// TODO Auto-generated method stub
}
}
抽象类成员的特点:
成员变量
可以有成员变量
可以有常量
成员方法
可以有抽象方法
可以有非抽象方法
构造方法
可以有构造方法的,需要对抽象类的成员变量进行初始化
public class AbstractDemo03 {
public static void main(String[] args) {
Dog03 d = new Dog03();
d.darking();
}
}
abstract class Animal03{
String name = "哮天犬";
final int num = 10;
public abstract void eat();
public void run() {}
public Animal03() {}
}
class Dog03 extends Animal03{
public void darking() {
System.out.println(name);
System.out.println(num);
}
@Override
public void eat() {
}
}
可能有的人看完以后会有一个疑问,为什么要使用抽象类呢,用户普通的类也可以啊(可以继承重写他的方法啊)?
当然这也是可以的,
当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。
但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。那该怎么办呢?
分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。
public class ExtendsDemo01 {
public static void main(String[] args) {
DotA d = new DotA();
d.start();
LOL l = new LOL();
l.start();
}
}
class Game{
String name;
double version;//版本号
String agent;//代理商
public void start() {
System.out.println("游戏启动!");
}
public void stop() {
System.out.println("游戏关闭!");
}
}
class DotA extends Game{
}
class LOL extends Game{
}
我呢就来一个我目前水平的简单理解:
比如说上面代码。游戏,我在游戏类中写了一个游戏启动的方法,并且呢写了它具体的启动方式(得有成千上万的代码吧)。但是如果说我们的DotA游戏和LOL游戏他们的启动方式不一样呢,那我们前面做的不就白瞎了吗?我们还得从新写的他的方法体。所以呢,我们干脆就把上面启动游戏的方法体给删除了,直接就变成这样了:
public abstract void start();
然后再把类改成抽象类,在具体游戏类型中写具体启动游戏的方法。哈哈哈,这样是不是觉得使用抽象类挺好的啊