现实中问题引入

现实中一类具有共同特征的类,但是无法具体实现。,比如我们定义了一个几何类,叫做Shape,我们有一个方法要计算周长,直接在每个子类实现虽然可以,但是无法通过Shape定义的实例来访问到这个计算周长的方法了。

抽象类和抽象方法:

抽象类和抽象方法都必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里面可以没有抽象方法。

具体规则如下:

1)抽象类必须用abstract修饰符修饰;

2)抽象方法也必须用abstract修饰符修饰;

3)抽象方法不能有方法体

4)抽象类不能被实例化,不能用new创建实例。

5)含有抽象方法的类,只能被定义成抽象类

语法:abstract 修饰

例如:平面图形类/三角形类

package com.zmd.study.abstract_example;

/**
* @ClassName PlaneFigure
* @projectName: object1
* @author: Zhangmingda
* @description: 抽象一个平面图形类,都有获取类型和周长的方法
* date: 2021/3/30.
*/
public abstract class PlaneFigure {
/**
* 获取平面图形的类型
*/
public abstract String getType(); /**
* 获取平面图形的周长
*/
public abstract double getPerimeter();
}

三角形类继承抽象类平面图形类

package com.zmd.study.abstract_example;

/**
* @ClassName Triangle
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/3/30.
*/
public class Triangle extends PlaneFigure {
/**
* 三角形的三边长类型定义
*/
private double a;
private double b;
private double c; /**
* 构造方法,创建三角形实例必须提供三边长度
*/
public Triangle(double a, double b, double c) {
/**
*@params [a, b, c] 三角形三边长度
*@return null
*@创建时间 2021/3/30
*/
if(a+b < c || a+c < b || b+c < a){
System.out.println("Failed!:三角形的两边之和必须大于第三边");
return;
}
this.a = a;
this.b = b;
this.c = c;
} @Override
public String getType() {
if(a+b < c || a+c < b || b+c < a){return "未知图形";}
return "三角形";
} @Override
public double getPerimeter() {
return a + b + c;
} }

测试类

package com.zmd.study.abstract_example;

public class AbstractTesst {
public static void main(String[] args) {
PlaneFigure planeFigure = new Triangle(3,4,5);
System.out.println(planeFigure.getType());
System.out.println(planeFigure.getPerimeter());
}
/**
* 三角形
* 12.0
*/
}

抽象类的作用

抽象类只能被当成父类来继承,抽象类是从多个具体类中抽象出来的父类。。是从多个具有相同特征的类中抽象出来的一个抽象类,可以作为子类的模板,从而避免子类涉设计的随意性。

抽象类是一种模板设计思路,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展和改造。实际应用中子类总体上会大致保留抽象类的行为方式。

汽车抽象类 和具体车型类案例

目录树:

Vehicle:

  -Vehicle.java //汽车抽象类

  -Car.java

  -Bus.java

  -CarType.java  //小汽车枚举类型

  VehicleTest.java

// Vehicle.java

package Vehicle;

public abstract class Vehicle {//用abstract 修饰的类叫做抽象类
//用abstract 修饰的方法叫做抽象方法,没有方法体
public abstract double getRent(int days);
}
//CarType.java 

package Vehicle;
/**
* @author: Zhangmingda
* @description:自定义车型:两箱、三箱,SUV、MPV 等,
* 可以看做是一组常量的组合,类似一年只有四个季度
* date: ${DATE}.
*/
public enum CarType {
HATCHBACK,THREECOMPARTMENT, SUV, MPV
//分别代表两箱,三箱,SUV,MPV(商务车)
}

//Car.java

//Car.java

package Vehicle;

public class Car extends Vehicle{
CarType type; //使用枚举类型避免出错 //重写父类的抽象方法
@Override
public double getRent(int days) {
switch (type){
case HATCHBACK://IDEA智能识别自定义的枚举可选类型
return 200 * days;
case THREECOMPARTMENT:
return 300 *days;
case SUV:
return 350 * days;
case MPV:
return 150 * days;
default:
return 800 * days;
}
}
}
//Bus.java

package Vehicle;

/**
* @author: Zhangmingda
* @description: XXX
* date: 2019/12/3.
*/
public class Bus extends Vehicle{
//大巴车定义自己的座位数属性
int seats;
//重写父类的抽象方法父类要求返回double类型,子类则也要求返回double
@Override
public double getRent(int days) {
if(seats > 0 && seats <= 18){
return 400 * days; //不同的座位数每日租金不同,返回计算结果不同
}else if(seats > 18 && seats <= 25 ){
return 1000 * days;
}else if(seats > 25 && seats <= 51 ) {
return 1500 * days;
}else{
return 2000 *days;
} }
}
//VehicleTest.java

package Vehicle;
import java.util.Scanner;
/**
* @author: Zhangmingda
* @description: 测试不同车的租金
* date: 2019/12/3.
*/
public class VehicleTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//选中代码,快捷键Ctrl + Alt + T 用代码包裹
while (true) {
System.out.print("请输入要选择的种类:\n1 小汽车、2 Bus 7座以上汽车 3 退出:");
int chose = sc.nextInt();
if(chose == 1){
Car car = new Car();
System.out.print("请选择汽车车型:1、两箱 2、三箱 3、SUV 4、PMV(商务)");
chose = sc.nextInt();
//根据选择计算租金
switch (chose){
case 1:
car.type = CarType.HATCHBACK;break;
case 2:
car.type = CarType.THREECOMPARTMENT;break;
case 3:
car.type = CarType.SUV;break;
case 4:
car.type = CarType.MPV;break;
default:
System.out.println("输入有误!以三箱做计算");
car.type = CarType.THREECOMPARTMENT;
break;
}
//车型信息确定。开始计算租金。这里定义一个单独的方法来计算,和计算bus车型共用
calculate(car);
}else if(chose == 2) {
//确定选择bus的作为数
Bus bus = new Bus();
System.out.print("请选择作为数:1、18座 2、 19-25座 3、26-51座: " );
chose = sc.nextInt();
bus.seats = chose;
//车型信息确定。开始计算租金。这里定义一个单独的方法来计算,和计算bus车型共用
calculate(bus);
}else {
//return;
System.exit(0);//退出JVM虚拟机
}
} } private static void calculate(Vehicle vehicle) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要租用的天数:");
int days = scanner.nextInt();
System.out.println("您的租金为:" + vehicle.getRent(days) ); }
}
//模拟计算机USB接口应用
//目录usb
// Computer.java 计算机类
// Disk.java 磁盘类实现USB接口
// Printer.java 打印机类 实现USB接口
// Usb.java 接口规范
// 接口
package usb;

/**
* @author: Zhangmingda
* @description: 定义一个接口,供任何USB设备相互对接
* date: 2019/12/3.
*/
public interface Usb {
void connect();
void disconnect();
}

package usb;

/**
* @author: Zhangmingda
* @description: XXX
* date: 2019/12/3.
*/
public class Printer implements Usb {
@Override
public void connect() {
System.out.println("打印机已连接。");
} @Override
public void disconnect() {
System.out.println("打印机已断开连接,可以拔出了!");
}
}
package usb;

/**
* @author: Zhangmingda
* @description: XXX
* date: 2019/12/3.
*/
public class Disk implements Usb {
@Override
public void connect() {
System.out.println("硬盘已连接。");
} @Override
public void disconnect() {
System.out.println("硬盘已断开连接,可以拔出了!");
}
}
package usb;

/**
* @author: Zhangmingda
* @description: 定义计算机可以插入USB设备、移除USB设备功能
* date: 2019/12/3.
*/
public class Computer {
Usb slot; //定义Usb 插槽,类变量
//把USB设备插入USB卡槽,需要通过参数接收一个USB设备,实现了一个USB接口就行
public void insert( Usb device){
slot = device;//通过赋值模拟设备插在USB口中
slot.connect();//插上就自动连接
}
public void pullout(Usb device){
if(this.slot == null){
System.out.println("USB口没有设备");
return;
}
device.disconnect();
this.slot = null;
System.out.println("设备已拔出");
}
}
package usb;

/**
* @author: Zhangmingda
* @description: 测试计算机插拔 实现接口的设备
* date: 2019/12/3.
*/
public class ComputerTest {
public static void main(String[] args) {
//建立一个计算机对象、磁盘、打印机
Computer computer = new Computer();
Disk disk = new Disk();
Printer printer = new Printer();
//模拟插入拔出操作
computer.insert(disk);
computer.pullout(disk);
computer.insert(printer);
computer.pullout(printer);
computer.pullout(printer); }
}
 

java 、abstract修饰的【抽象类】【比如几何图形类】的更多相关文章

  1. java 接口 继承 接口 抽象类 继承 实体类

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 接口 可以 继承 接口 抽象类 可以 实现 接口 抽象类 继承实体类 需要 实体类 有 ...

  2. Java的修饰符

    转自:http://blog.csdn.net/manyizilin/article/details/51926230#L42 修饰符: 像其他语言一样,Java可以使用修饰符来修饰类中方法和属性.主 ...

  3. 十、Java基础---------面向对象之抽象类与接口

    抽象类(abstract)     当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体.但是在某些情况下,某个父类只是知道子类应该包含怎样的方 ...

  4. Java中多态、抽象类和接口

    1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: ...

  5. JAVA中接口与抽象类

    抽象类总结 抽象类的概念:是使用关键字abstract修饰的类就是抽象类: 抽象类的产生:当多个不能相互继承的类具有相同的功能时,就需要将共同的信息向上抽取,放到公共的父类中:如果公共的父类只能描述所 ...

  6. Java中的继承抽象类和接口

    一.总结 1.使用extends关键字继承,eg: class Student extends Persion { ...}; 2.Java编程规范中类的首字母大写,方法的首字母小写单词首字母代谢,e ...

  7. Java 5- Java 修饰符

    Java 修饰符 Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: public class ...

  8. abstract修饰符

    abstract(C# 参考) abstract 修饰符指示所修饰的内容缺少实现或未完全实现. abstract 修饰符可用于类.方法.属性.索引器和事件. 在类声明中使用 abstract 修饰符以 ...

  9. Java中接口和抽象类的区别?

    抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public ...

  10. 【Java】接口和抽象类总结

    一.接口 1.1 成员变量(其实是常量) 1.2 方法 二.抽象类 2.1 成员变量 2.2 方法 一.接口 1.1 成员变量(其实是常量) 成员变量默认用 public static final修饰 ...

随机推荐

  1. AT3945 [ARC092D] Two Faced Edges

    要求,翻转一条边,强连通分量个数是否会改变. 考虑连通分量个数会改变的因素: 即\(v\to u\)是否成立,以及翻转前,是否有一条\(u \to v\)的路径不经过该条边 以上当只有一个满足时,连通 ...

  2. [省选联考 2021 A/B 卷] 宝石

    大概是一眼看出来是这个给定序列在树上序列上按顺序跑最大匹配. 然后考虑维护向上和向下的链的值. 大概的做法是用倍增维护,考虑\(f_{u,i}\)是\(c_u\)在序列里的位置向后匹配\(2^i\)位 ...

  3. Atcoder Grand Contest 034 F - RNG and XOR(FWT)

    Atcoder 题面传送门 & 洛谷题面传送门 tsc 考试前 A 的题了,结果到现在才写这篇题解--为了 2mol 我已经一周没碰键盘了,现在 2mol 结束算是可以短暂的春天 短暂地卷一会 ...

  4. 【Perl】如何安装Bioperl模块?

    目录 失败尝试一:使用cpanm 失败尝试二:使用CPAN 成功尝试:直接conda安装bioperl 没有尝试:源码安装bioperl 生信软件绕不过Perl,Perl绕不过Bioperl.而Bio ...

  5. UE4之Slate: App启动与最外层Runtime结构

    UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...

  6. java Random()用法

    1.random.nextInt() random.nextIn()的作用是随机生成一个int类型,因为int 的取值范围是 -2147483648--2147483647 ,所以生成的数也是处于这个 ...

  7. MySQL自我保护参数

    上文(MySQL自我保护工具--pt-kill )提到用pt-kill工具来kill相关的会话,来达到保护数据库的目的,本文再通过修改数据库参数的方式达到阻断长时间运行的SQL的目的. 1.参数介绍 ...

  8. 关于浏览器,从输入URL到呈现页面过程!(主讲TCP/IP协议)

    一.文本对话--从请求到响应 我们在浏览器中输入一个 URL,回车之后便会在浏览器中观察到页面内容.实际上这个过程是: (1)浏览器向网站所在的服务器发送了一个 Request(请求) (2)网站服务 ...

  9. 【leetcode】563. Binary Tree Tilt

    Given the root of a binary tree, return the sum of every tree node's tilt. The tilt of a tree node i ...

  10. C++ 写出这个数

    题目如下: 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这里保证 n 小于 1. 输出格式: 在一行内 ...