5.1.6 抽象类

有时候我们无法说出具体是什么,只能用于标识一个类型,比如图形,就可作为抽象类。虽然无法具体描述图形,但是图形通常都有面积、周长。这种时候就可用抽象类标识。

抽象类使用abstract标识来标识,特征如下:

  1. 可以写抽象方法,抽象方法同样使用abstract关键字标识,不能有大括号方法体,结尾用分号;
  2. 可以写非抽象方法,与普通类中方法的写法相同;
  3. 可以被继承,或者说不被继承的抽象类没有任何意义,继承抽象类的非抽象类,必须实现抽象方法;
  4. 抽象类不能使用new 实例化,它指代的是一类东西的共同特征,无具体的描述。实例化抽象类类似于“你把人找来”,没有具体的指代,无法知道指的是哪个人。

代码如下:

public abstract class Shape{

private int tmpA;

private int tmpB;



//1. 可以写抽象方法,抽象方法同样使用abstract关键字标识,不能有大括号方法体,结尾用分号;

public abstract double getArea();

public abstract double getPerimeter();



//2. 可以写非抽象方法,与普通类中方法的写法相同;

public int getTmpA() { return tmpA; }



public void setTmpA(int tmpA) { this.tmpA = tmpA; }



public int getTmpB() { return tmpB; }



public void setTmpB(int tmpB) { this.tmpB = tmpB; }



@Override

public String toString() {

return "I am shape";

}

}
public class Circle extends Shape {

private int r;



public int getR() { return r; }



public void setR(int r) { this.r = r; }



//3. 可以被继承,或者说不被继承的抽象类没有任何意义,继承抽象类的非抽象类,必须实现抽象方法;

@Override

public double getArea() { return PI*r*r; }



@Override

public double getPerimeter() { return 2*PI*r; }



@Override

public String toString() {

return "r="+r;

}

}
public class Square extends Shape {

double a;

double b;



public double getA() { return a; }



public void setA(double a) { this.a = a; }



public double getB() { return b; }



public void setB(double b) { this.b = b; }



//3. 可以被继承,或者说不被继承的抽象类没有任何意义,继承抽象类的非抽象类,必须实现抽象方法;

@Override

public double getArea() {

return a*b;

}



@Override

public double getPerimeter() {

return a+a+b+b;

}

@Override

public String toString() {

return "a="+a+" b="+b;

}

}
public class Main {

public static void main(String[] args){

Main solution = new Main();

Circle c = new Circle();

c.setR(5);

solution.printShapeAreaPerimeter(c);



Square s = new Square();

s.setA(3);

s.setB(5);

solution.printShapeAreaPerimeter(s);

//4. 抽象类不能使用 new 实例化,它指代的是一类东西的共同特征,无具体的描述。

// Shape test = new Shape();

//Error:(26, 22) java: com.dyy.jdk8.test.Shape是抽象的; 无法实例化

}



private void printShapeAreaPerimeter(Shape shape){

System.out.println(shape.getArea());

System.out.println(shape.getPerimeter());

}

}

5.1.7 受保护的访问

有些时候,一些方法只希望子类去修改,而不希望外界进行调用,此时可以用protected关键字,比如Shape中设置各自形状的名称

public abstract class Shape{

private int tmpA;

private int tmpB;

//1. 可以写抽象方法,抽象方法同样使用abstract关键字标识,不能有大括号方法体,结尾用分号;

public abstract double getArea();

public abstract double getPerimeter();

protected abstract void setName(String name);

public abstract String getName();

//2. 可以写非抽象方法,与普通类中方法的写法相同;

public int getTmpA() { return tmpA; }



public void setTmpA(int tmpA) { this.tmpA = tmpA; }



public int getTmpB() { return tmpB; }



public void setTmpB(int tmpB) { this.tmpB = tmpB; }



@Override

public String toString() {

return "I am shape";

}

}
public class Circle extends Shape {

private int r;

private String name;



public Circle(){

setName("circle");

}

public int getR() { return r; }



public void setR(int r) { this.r = r; }



//3. 可以被继承,或者说不被继承的抽象类没有任何意义,继承抽象类的非抽象类,必须实现抽象方法;

@Override

public double getArea() { return PI*r*r; }



@Override

public double getPerimeter() { return 2*PI*r; }



@Override

protected void setName(String name) {

this.name = name;

}



@Override

public String getName() {

return name;

}



@Override

public String toString() {

return "r="+r;

}

}
public class Square extends Shape {

private double a;

private double b;

private String name;

public Square(){

setName("square");

}



public double getA() { return a; }



public void setA(double a) { this.a = a; }



public double getB() { return b; }



public void setB(double b) { this.b = b; }



//3. 可以被继承,或者说不被继承的抽象类没有任何意义,继承抽象类的非抽象类,必须实现抽象方法;

@Override

public double getArea() { return a*b; }



@Override

public double getPerimeter() { return a+a+b+b; }



@Override

protected void setName(String name) { this.name = name; }



@Override

public String getName() { return name; }



@Override

public String toString() {

return "a="+a+" b="+b;

}

}
public class Main {

public static void main(String[] args){

Main solution = new Main();

Circle c = new Circle();

c.setR(5);

solution.printShapeAreaPerimeter(c);



Square s = new Square();

s.setA(3);

s.setB(5);

solution.printShapeAreaPerimeter(s);

//4. 抽象类不能使用 new 实例化,它指代的是一类东西的共同特征,无具体的描述。

// Shape test = new Shape();

//Error:(26, 22) java: com.dyy.jdk8.test.Shape是抽象的; 无法实例化

}



private void printShapeAreaPerimeter(Shape shape){

System.out.println(shape.getArea());

System.out.println(shape.getPerimeter());

System.out.println(shape.getName());

}

}

执行结果:

《Java 核心技术 卷1》 笔记 第五章 继承(3)_后端

 系列内容

《Java 核心技术 卷1》 笔记:第一章 Java程序设计概述

《Java 核心技术 卷1》 笔记:第二章 Java程序设计环境

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(1)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(2)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(3)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(4)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(5)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(6)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(7)大数处理、数组、多维数组、控制台传参

《Java 核心技术 卷1》 笔记 第四章:类与对象

《Java 核心技术 卷1》 笔记 第四章:类与对象(2) GregorianCalendar 与 类的基本组成

《Java 核心技术 卷1》 笔记 第四章:类与对象(3) 构造器全局私有方法

《Java 核心技术 卷1》 笔记 第四章:类与对象(4) 静态字段+静态方法+工厂方法

《Java 核心技术 卷1》 笔记 第四章:类与对象(5) 形参与实参 构造器的默认值与默认构造

《Java 核心技术 卷1》 笔记 第四章:类与对象(6) 构造器调用与初始化块

《Java 核心技术 卷1》 笔记 第四章:类与对象(7) 注释、JavaDoc与类设计

《Java 核心技术 卷1》 笔记 第五章 继承

《Java 核心技术 卷1》 笔记 第五章 继承(2)

喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。

关注公众号,互相学习:钰娘娘知识汇总

《Java 核心技术 卷1》 笔记 第五章 继承(3)_后端_02