一、abstract是什么

1、话题引入

00012.01抽象类与抽象方法(abstract)_抽象方法


00012.01抽象类与抽象方法(abstract)_抽象类_02


从上面可以看出不能这样使用,为什么呢?因为abstract是关键字

00012.01抽象类与抽象方法(abstract)_抽象类_03


00012.01抽象类与抽象方法(abstract)_抽象方法_04

2、面向对象的特征

我们面试的时候经常会被问到的问题就是面向对象的特征

那么网上公认的答案是:

1、面向对象的基本特征:封装、继承、多态

2、面向对象的特征: 封装、继承、多态、抽象

那么什么叫抽象呢?

抽象就是具体的反义词,这个没有异议吧,语文都学过

和模糊、不确定、不清晰类似

那下面我们思考什么时候会用到抽象?

当我们在声明一个类的时候,某些方法实现不清楚、或者无法给出具体实现的时候,要等到具体的子类中才能给出具体的实现,这样的方法,我们就可以声明为抽象方法

有一个最好理解的例子

我们在声明一个图形类的时候 Graphic,我们知道在图形这个事物中不管是什么图形,都有两个特征:(1)、求面积(2)、求周长

我们看下面的例子

以前我们在Graphic类里面为了语法正确不得不写一段毫无意义的代码,实际上这这段代码我们是无法给出一个清晰的解决方案的,因为你不知道它是什么图形,需要子类重写

00012.01抽象类与抽象方法(abstract)_抽象方法_05

3、抽象方法

那么这样的方法我们就完全可以声明为抽象方法
【注意】:抽象方法没有方法体

语法格式:其它修饰符 abstract 返回值类型 方法名 (形参列表);

00012.01抽象类与抽象方法(abstract)_抽象类_06


修正如下

00012.01抽象类与抽象方法(abstract)_子类_07


这样我们就提到了抽象类的概念

4、抽象类:如果一个类中包含了抽象方法,那么这个类必须是一个抽象类

抽象类和普通类有什么不同,即抽象类的特点:
(1)、抽象类不能实例化,不能直接创建对象,或者说不能创建抽象类的对象
(2)、如果子类继承了抽象类,那么必须重写父类的所有抽象方法,否则子类也得是一个抽象类
(3)、抽象类也有构造器,这个构造器不是为了创建抽象类自己的对象用的,而是为子类创建对象服务的
(4)、抽象父类与子类的对象之间可以构成多态
(5)、抽象类中也可能没有抽象方法

00012.01抽象类与抽象方法(abstract)_抽象方法_08


那么我们写一个子类去基础图形类 Graphic行不行呢?实际上直接继承也报错了,我们看报错提示

00012.01抽象类与抽象方法(abstract)_抽象方法_09


如上图,基础的什么方法其实都告诉你了 就是getArea() 方法

eclipse提供了两种解决方案

00012.01抽象类与抽象方法(abstract)_子类_10


我们一般子类里面重写那么怎么重写呢?

00012.01抽象类与抽象方法(abstract)_抽象类_11


00012.01抽象类与抽象方法(abstract)_抽象类_12


我们手动改一下自动生成的代码

00012.01抽象类与抽象方法(abstract)_子类_13


然后就是加 构造器、getset 方法这些了

00012.01抽象类与抽象方法(abstract)_抽象方法_14


最终效果如下

00012.01抽象类与抽象方法(abstract)_子类_15


5、回顾

回顾一下,

(1)父类的构造器能不能被子类继承?

答:不能

(2)抽象类有构造器吗?

答:抽象类也有构造器,这个构造器不是为了创建抽象类自己的对象用的,而是为子类创建对象服务的

(4)抽象父类与子类之间可以构成多态吗

能,实际开发当中经常用的一种方式

00012.01抽象类与抽象方法(abstract)_抽象方法_16


(5)、抽象类中也可能没有抽象方法,目的是什么呢?

a、为了多态的应用

b、不希望你创建父类对象(希望你创建子类的对象)

00012.01抽象类与抽象方法(abstract)_抽象类_17

完整代码如下:

package com.atguigu.test02.abstract_;

/*
* 面试题:
* 1、面向对象的基本特征:封装、继承、多态
* 2、面向对象的特征:封装、继承、多态、抽象
*
* 抽象:abstract
* 是具体的反义词
* 和模糊,不确定,不清晰有的类似
*
* 1、什么情况下会用到抽象?
* 当我们在声明一个父类时,某个/些方法的实现不清楚,或者说无法给出具体的实现,
* 要等到具体的子类中才能给出具体的实现,那么这样的方法,就可以声明为抽象方法。
*
* 抽象方法没有方法体
*
* 2、抽象方法
* 语法格式:
* 【其他修饰符】 abstract 返回值类型 方法名(【形参列表】);
*
* 3、抽象类
* 如果一个类中包含了抽象方法,那么这个类必须是一个抽象类。
* 语法格式:
* 【其他修饰符】 abstract class 抽象类名{
* 【其他修饰符】 abstract 返回值类型 方法名(【形参列表】);
* }
*
*
* 例如:我们声明一个图形类:Graphic
* 我们知道在图形这个事物中,不管是什么图形,都有两个特征:(1)求面积(2)求周长
*
* 4、抽象类的特点
* (1)抽象类不能实例化,不能直接创建对象或者说,不能创建抽象类的对象
* (2) 如果子类继承了抽象类,必须重写父类的所有的抽象方法,否则子类也得是一个抽象类
* (3)抽象类也有构造器,这个构造器不是为了创建抽象类自己的对象用的,而是为子类创建对象服务的
* (4)抽象父类与子类的对象之间可以构成多态引用
* (5)抽象类中也可能没有抽象方法,目的就是不能你创建它的对象
* 如果一个类中包含了抽象方法,那么这个类必须是一个抽象类。
*/
public class TestAbstract {
public static void main(String[] args) {
// Graphic g1 = new Graphic();//不能创建抽象类的对象

Graphic g1 = new Circle(1.2);//多态引用
System.out.println("面积:" + g1.getArea());
}
}
abstract class Graphic{
private String name;
public Graphic(String name) {
super();
this.name = name;
}
public Graphic() {
super();
}
/*public double getArea(){
return 0.0;
}*/

public abstract double getArea();

}
class Circle extends Graphic{
private double radius;

public Circle() {
super();
}

public Circle(double radius) {
super();
this.radius = radius;
}
public Circle(String name, double radius) {
super(name);
this.radius = radius;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}

@Override
public double getArea() {
//return 3.14 * radius * radius;
return Math.PI * radius * radius;
}

}

//像这种没有抽象方法的抽象类,存在的意义
//(1)为了多态的应用,因为父类可以管理各种子类对象
//(2)不希望你创建这个父类的对象,而是创建子类的对象
abstract class Person{

}
class Woman extends Person{

}
class Man extends Person{

}

总结:

1、abstract 抽象的
2、可以修饰什么?
类和方法
3、修饰类的话,不能和其它的修饰符一起用
修饰类的 修饰符
public、缺省、final
abstract和final不能一起修饰类
4、修饰方法和哪些修饰符不能一起用
我们知道修饰方法除了public、private外还有4种权限修饰符,分别是static、final、abstract、native

  • (1)final,abstract不行 因为final不能被重写
  • (2)static,abstract不行 因为static不能被重写
  • (3)native,abstract不行 因为都没有方法体,不知道是什么情况,会有歧义
  • (4)private,abstract不行 因为private不能被重写

public class TestModifier {
// public native abstract void test();
}