一、什么是抽象类
是一种无法被实例化的类,它的主要是为了让子类去实现这些抽象方法来达到某种特定的功能。抽象类的本质为同一种类的事物提供功能,不给具体实现,让它的子类根据自身的实际情况实现这个功能。
二、为什么要使用抽象类
为了减少代码的重复编写,提高代码的重用性。例如,坐公交和坐出租车都需要计算收费金额,我们就要在公交和出租的不同类中重复编写计费方式,而这时我们发现公交和出租都属于交通工具,于是则可以将交通工具作为抽象类,让公交类和出租车类都去继承交通工具这个抽象类,那么我们就可以只在交通工具类中编写一个计费的抽象方法,在公交和出租的类中我们只需要编写具体的计费方式即可,有效的减少代码的重复编写,提高代码的重用性。
public abstract class Transportation{
//创建抽象类中的抽象方法
public abstract void charge();
}
public class Taxi extends Transportation{
@Override
public void charge() {
System.out.println("出租车按每公里1.5收费");
}
}
public class Bus extends Transportation{
@Override
public void charge() {
System.out.println("公交按每人1元收费");
}
}
public class TestMain {
public static void main(String[] args) {
//创建Taxi对象
Taxi taxi = new Taxi();
Taxi.charge();
//创建Bus对象
Bus bus = new Bus();
bus.charge();
}
}
三、如何创建一个抽象类
通过abstract关键字创建抽象类
public abstract class Person {
}
四、抽象类中都可以包含什么
抽象类---实例变量,静态成员变量,构造方法,实例方法,静态方法,抽象方法
其中抽象方法有以下特征:
1.使用abstract关键字修饰
2.没有方法体“{}”
五、抽象类的具体用法
1.抽象类中可以有抽象方法,可以一个抽象方法都没有
2.当一个普通的java类继承一个抽象类,就需要实现抽象类提供的所有抽象方法,也可以将这个普通的java类改成抽象类
3.抽象类可以继承抽象类
4.抽象类不能通过new+构造方法的形式创建对象,可以通过上转型对象完成抽象类的对象的创建
5.当方法参数是抽象类类型的时候,可以传递上转型对象,也可以是抽象类的子类对象。
//上述第5条,代码演示
public abstract class People {
//创建一个实例变量
public String shili_bianliang = "实例变量";
//创建一个静态变量
public static String static_bianliang = "静态变量";
//创建一个构造方法
public People(){
System.out.println("People类的构造方法");
}
//创建一个实例方法
public void shiliFangFa(){
System.out.println("People类的实例方法");
}
//创建一个静态方法
public static void staticFangFa(){
System.out.println("People类的静态方法");
}
//创建一个抽象方法
/*
抽象方法,用abstract修饰,不能使用static修饰,没有方法体
抽象方法就是为子类提供具体实现功能
抽象类中可以有抽象方法,也可以一个抽象方法都没有
普通java类中一定没有抽象方法
*/
public abstract void chouXiang();
}
public class Man extends People{
public void manTest(){
System.out.println("子类中的实例方法");
}
@Override
public void chouXiang() {
}
}
public class AbstractCanShu {
public void abstractCanshu(People people){
System.out.println("AbstractCanShu的实例方法");
}
}
public class TestMain {
public static void main(String[] args) {
//创建AbstractCanShu类对象
AbstractCanShu abstractCanShu=new AbstractCanShu();
//创建上转型对象
People people = new Man();
abstractCanShu.abstractCanshu(people);
//创建抽象类子对象
Man man = new Man();
abstractCanShu.abstractCanshu(man);
}
}
六、什么是上转型对象及基本特征
1.上转型对象---子类对象赋值给他的父类变量
2.子类对象赋值给他的父类变量,此时父类变量认为自己保存的是父类的对象
3.上转型对象只能访问父类的变量和方法,不能访问子类自己的变量和方法
如果一定要使用上转型对象访问子类自己的变量和方法要将上转型对象强制类型转换成子类对象
格式: 低类型 低变量=(低类型)上转型对象
package com.wangxing.extendstest.demo4;
//父类
public class FuClass {
public void testFuLei(){
System.out.println("FuClass类的实例方法");
}
}
package com.wangxing.extendstest.demo4;
//子类
public class SunClass extends FuClass{
//Sunclass类自己的实例方法
public void testSun(){
System.out.println("SunClass类的实例方法");
}
}
package com.wangxing.extendstest.demo4;
public class TestMain {
public static void main(String[] args) {
//上转型对象---子类对象赋值给他的父类变量
//将子类对象转换成了父类对象
FuClass f=new SunClass();
f.testFuLei();//父类的方法
//f.testSun(); //子类的方法
//如果一定要使用上转型对象访问子类自己的变量和方法
//将上转型对象强制类型转换成子类对象
//低类型 低变量=(低类型)上转型对象
SunClass s=(SunClass)f;
s.testSun();
}
}
七、乘坐不同车型,计费方式不同的是演示实例
1.用户选择乘坐方式,给出提示选择,输入不正确,提示重新输入,正确下一步
2.录入公里数,数据为负数时提示重新输入
3.数据均正常,按照计价规则计算费用并输出
package com.homework.test3;
//创建一个汽车的抽象类,用于定义支付方式功能
public abstract class Cars {
//该方法有一个距离参数,需要录入用户距离多少
public abstract void payFor(float distance);
}
package com.homework.test3;
import java.util.Scanner;
//定义公交的具体收费方式
public class Bus extends Cars{
@Override
public void payFor(float distance) {
Scanner scanner_distance = new Scanner(System.in);
while(true) {
//公里数小于0,提示输入不正确,大于0 ,计算费用
if (distance < 0) {
System.out.println("距离数据错误,无法计算,请重新输入距离");
distance = scanner_distance.nextFloat();
} else {
System.out.println("公交乘坐费用为:每人1元");
break;
}
}
}
}
package com.homework.test3;
import java.util.Scanner;
//定义出租车的具体收费方式,需要继承Cars抽象类
public class Taxi extends Cars{
//定义出租车的初始费用
public float start_money = 8;
//定义总费用
public float sum = 0;
@Override
//定义出租车具体收费标准,初始费用8元,超过10公里,每公里1.25
public void payFor(float distance) {
Scanner scanner_distance = new Scanner(System.in);
while(true){
if(distance<0){
System.out.println("距离数据错误,无法计算,请重新输入距离");
distance = scanner_distance.nextFloat();
}else if(distance>0 && distance<=10){
System.out.println("您本次乘坐需花费:"+start_money+"元");
break;
}else{
System.out.println(distance);
sum = start_money+distance*1.25f;
System.out.println("您这次乘坐的总费用为:"+sum+"元");
break;
}
}
}
}
package com.homework.test3;
import java.util.Scanner;
//定义专车的计费方式
public class VipCar extends Cars{
//定义专车的初始费用
public float start_money = 30;
//定义总费用
public float sum = 0;
@Override
//定义专车具体收费标准,初始费用30元,超过15公里,每公里2.5
public void payFor(float distance) {
Scanner scanner_distance = new Scanner(System.in);
while(true){
if(distance<0){
System.out.println("距离数据错误,无法计算,请重新输入距离");
distance = scanner_distance.nextFloat();
}else if(distance>0 && distance<=15){
System.out.println("您本次乘坐需花费:"+start_money+"元");
break;
}else{
sum = start_money+distance*2.5f;
System.out.println("您这次乘坐的总费用为:"+sum+"元");
break;
}
}
}
}
package com.homework.test3;
import java.util.Scanner;
//主方法入口
public class TestMain {
public static void main(String[] args) {
//何时退出
boolean exit = true;
//创建scanner_travel_mode键盘输入对象,录取乘坐方式
Scanner scanner_travel_mode =new Scanner(System.in);
//创建scanner_distance键盘输入对象,录取公里数
Scanner scanner_distance = new Scanner(System.in);
while (true){
System.out.println("-------------------------欢迎选择乘坐方式-----------------------");
System.out.println("请输入出租or公交or专车or退出,我们将根据您的选择,为您提供服务");
//将录入的乘坐方式保存在travel_mode变量里
String travel_mode = scanner_travel_mode.next();
//为了保存Cars对象
Cars cars = null;
//判断输入的内容方式是哪种
while (true){
//输入已有方式,跳出循环,采集公里数,否则重新输入
if("出租".equals(travel_mode)){
cars = new Taxi();
break;
}else if("公交".equals(travel_mode)){
cars = new Bus();
break;
}else if("专车".equals(travel_mode)){
cars = new VipCar();
break;
}else if ("退出".equals(travel_mode)){
exit = false;
break;
}else {
System.out.println("未按照提示输入,请重新输入:");
travel_mode = scanner_travel_mode.next();
}
}
//选择的是正确方式,采集公里数,计算费用;如果选择退出,退出程序
if (exit == true){
System.out.println("请输公里数");
//将录入的公里数保存在kilometer变量里
float kilometer = scanner_distance.nextFloat();
cars.payFor(kilometer);
System.out.println();
} else {
System.out.println("------------------------感谢使用----------------------------");
System.out.println();
break;
}
}
}
}