day06-07面向对象(高级)

面向对象(高级)

知识回顾:

1.面向对象基础


类的定义
对象的使用
private关键字
this关键字
封装
构造方法
JavaBean

2.API 的使用

知识回顾
Scanner
Random
String
Date

1.继承

查看下述代码: 发现有什么问题?

在这里插入图片描述

你所抽取的代码没有了,怎么办?我们再写一个类,先不用管它叫什么名字,但是里面一定包含着之前看到的相同的内容,是不是长这样啊(切PPT)此时问题来了,之前的代码还对吗?是不是少东西了?所以必须有一种新的机制出现,保障学生和老师类与中间这个类产生一定的关系,有了这个关系之后,就可以实现和之前的类效果相同?这个关系就是我们要讲的继承。

在这里插入图片描述

1.继承概述

继承是面向对象三大特征之一。(封装,继承,多态)
可以使得子类具有父类属性方法,还可以在子类中重新定义,追加属性和方法。

2.练习:老师和学生

需求:定义老师类和学生类,然后写代码测试;最后找到老师类和学生类当中的共性内容,抽取出一个父类,用继承的方式改写代码,并进行测试

思路:
定义老师类(姓名,年龄,教书())
定义学生类(姓名,年龄,学习())
定义测试类,写代码测试
共性抽取父类,定义人类(姓名,年龄)
定义老师类,继承人类,并给出自己特有方法:教书()
定义学生类,继承人类,并给出自己特有方法:学习()
定义测试类,写代码测试

3.继承的格式:

1.格式:

public class 子类名 extends 父类名 { }

2.范例:

public class Zi extends Fu { }

Fu:是父类,也被称为基类、超类
Zi:是子类,也被称为派生类

3.继承中子类的特点:

一个子类只能有一个父类
子类可以有父类的内容
子类还可以有自己特有的内容

4.继承的好处和弊端

4.1 继承好处

提高了代码的复用性(多个类相同的成员变量/成员方法可以放到同一个类中)
提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

4.2 继承弊端

继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性

4.3 什么时候使用继承?

继承体现的关系:is a
假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承
举例:苹果和水果,猫和动物,猫和狗不是

5.探究继承的访问特性

5.1 成员变量的访问特性

在子类方法中访问一个变量
子类局部范围找
子类成员范围找
父类成员范围找
如果都没有就报错(不考虑父亲的父亲…)

总结:就近原则

public class Fu {
    int age = 18;
}
public class Zi extends Fu{
//    int age = 20;
    public void show(){
//        int age = 23;
        System.out.println(age);
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.show();
    }
}

5.1.1super 关键字

super 关键字的用法和 this 关键字的用法相似
this:代表调用该方法的对象(一般我们是在当前类中使用this,所以我们常说this代表本类对象的引用)
super:代表父类存储空间的标识(可以理解为父类对象引用)

关键字访问成员变量访问构造方法访问成员方法
thisthis.成员变量访问本类成员变量this(…)访问本类构造方法this.成员方法(…)访问本类成员方法
supersuper.成员变量访问父类成员变量super(…)访问父类构造方法super.成员方法(…)访问父类成员方法

子类中所有的构造方法第一行默认有个super();语句。

super访问构造方法只能出现在构造方法第一行

1.访问成员变量

public class Fu {
    int age = 18;
}
public class Zi extends Fu{
    int age = 20;
    public void show(){
        int age = 23;
        System.out.println(this.age);//20
        System.out.println(super.age);//18
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.show();
    }
}

2.访问构造方法

public class Fu {
String name;
int age;
    public Fu() {
    }
    public Fu(String name) {
        this.name = name;
    }
    public Fu(int age) {
        this.age = age;
        System.out.println("调用父类构造器");
    }

}
public class Zi extends Fu{
    String sex;
    int height;
    public Zi(int height) {
//        this(sex);
        super(18);
        this.height = height;

    }
    public Zi(String sex) {
        this.sex = sex;
        System.out.println("本类中调用其它构造器");
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi(180);
    }
}

3.访问成员方法

5.2 构造方法的访问特性

子类中所有的构造方法默认都会访问父类中无参的构造方法,为什么?
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
每一个子类构造方法的第一条语句默认都是:super()

如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
① 通过使用super关键字去显示的调用父类的带参构造方法
② 在父类中自己提供一个无参构造方法
推荐:自己给出无参构造方法

public class Fu {
    String name;
    int age;
    public Fu() {
        System.out.println("访问父类无参构造");
    }
    public Fu(String name) {
        this.name = name;
    }
    public Fu(int age) {
        this.age = age;
        System.out.println("调用父类构造器");
    }
}
public class Zi extends Fu {
    String sex;
    int height;
    public Zi() {
    }
    public Zi(int height) {
       this("男");
//        super(18);
        this.height = height;
    }
    public Zi(String sex) {
        this.sex = sex;
        System.out.println("本类中调用其它构造器");
    }
}
public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi(180);
    }
}

5.3 方法的访问特性

5.3.1继承中成员方法的访问特点

通过子类对象访问一个方法
子类成员范围找
父类成员范围找
如果都没有就报错(不考虑父亲的父亲…)

总结:就近原则

5.3.2 方法重写

1.方法重写概述
子类中出现了和父类中一模一样的方法声明

2.方法重写的应用
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,
又定义了子类特有的内容

3.@Override
是一个注解(注解后面会学习到)
可以帮助我们检查重写方法的方法声明的正确性

6. 练习: 项目经理和程序员

需求:请使用继承的思想设计出项目经理类和程序员类,并进行测试。

项目经理:
成员变量:工号,姓名,工资,奖金
成员方法:工作()

程序员:
成员变量:工号,姓名,工资
成员方法:工作()

员工:
成员变量:工号,姓名,工资
成员方法:工作()

项目经理继承自员工,添加一个新的成员变量奖金
程序员继承自员工,不需要添加新的成员

2.修饰符

接下来,我们来学习修饰符,在学习修饰符之前,我们先说一下修饰符的分类。

修饰符分为权限修饰符和状态修饰符,我们先来学习权限修饰符。

修饰符的分类

1.权限修饰符

2.状态修饰符

2.1 权限修饰符

修饰符同一个类中同一个包中不同包,但父子关系不同包,非父子关系
private
默认(缺省)
protected
public

2.2 状态修饰符

static(静态)

final(最终态)

2.21 static 关键字

static 静态修饰为所有对象使用
关键字是静态的意思,可以修饰成员方法,成员变量

static 修饰的特点
① 被类的所有对象共享,这也是我们判断是否使用静态关键字的条件
② 可以通过类名调用,当然,也可以通过对象名调用,推荐使用类名调用

解释:
JVM加载类:
所有的类都是在对其第一次使用时,动态加载到JVM中的。当程序创建第一个类的静态成员的引用时,就会加载这个类,进而可以得到该类的类型信息
即使在构造器之前并没有使用static关键字。因此,使用new操作符创建类的新对象也会被当做对类的静态成员的引用。
被static修饰的方法会首先被Classloader对象先加载进内存,而这个时候可能其它的非静态方法或者变量还没有被加载进来

2.22 static 的访问特点

非静态的成员方法

能访问静态的成员变量
能访问非静态的成员变量
能访问静态的成员方法
能访问非静态的成员方法

静态的成员方法
能访问静态的成员变量
能访问静态的成员方法

总结成一句话就是:静态成员方法只能访问静态成员

public class Non_Static {

    public static String name;
    String sex;
    public void play(){
        System.out.println("play");
    }
    public static void run(){
        System.out.println("run");
    }
    //非静态成员方法
    public void show(){
        System.out.println(name);
        System.out.println(sex);
        play();
        run();
    }
    public static void show2(){
        System.out.println(name);
        run();
    }
}

2.23 main 方法格式的详细说明

public static void main(String[] args) { }
public 被jvm调用,访问权限足够大
static 被jvm调用,不用创建对象,直接类名访问
void 被jvm调用,不需要给jvm返回值
main 一个通用的名称,虽然不是关键字,但是被jvm识别
String[] args 以前用于接收键盘录入的

Java执行的程序 参数1 参数2 参数3 第一个参数就是数组中的第一个元素
演示args接收数据

public static void main(String[] args) {
        System.out.println(args.length);
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }

在这里插入图片描述

2.24 static 的应用

工具类的特点
构造方法私有 举例:Math
成员用static修饰 (成员变量、成员方法)

2.25 final 关键字概述

在Math源码中 有个值 public static final double PI = 3.14159265358979323846; 这个值不能改变

final 关键字是最终的意思,可以修饰成员方法,成员变量,类
final 修饰的特点
修饰方法:表明该方法是最终方法,不能被重写
修饰变量:表明该变量是常量,不能再次被赋值
修饰类:表明该类是最终类,不能被继承

2.26 final 修饰局部变量

变量是基本类型:final 修饰指的是基本类型的数据值不能发生改变
变量是引用类型:final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的

   public void show2(final int a){
//        a = 5;//报错
    }
    public void show3(){
       final int  a = 5;
//       a = 6;//报错
    }
public class Test {
    public static void main(String[] args) {
        //final修饰基本类型变量
        final int age = 18;
//        age = 20;//报错
        //final修饰引用类型变量
        final People people = new People();
        people.setAge(18);
        people.setName("灰灰");
    }
}

2.27 Math类的使用

Math类留给学生作为课堂练习,或者晚上的作业。通过该练习看学员是否掌握类名.静态方法的使用。

Math类是:数学工具类,包含对数学运算的方法

帮助文档中,没有看到构造方法,因为成员都用static修饰了,可以通过类名直接访问

2.28 jar包和帮助文档

jar包:也就是后缀名为.jar 的文件,也叫做jar文件
JAR文件(Java归档,英语:JavaARchive)是一种软件包文件格式,一般情况下jar文件中打包了多个class文件
简单的理解:jar包就是.class文件的压缩包

jar包的使用

3.抽象类

抽象类的引入:在继承过程中提取公共方法和成员属性的过程中有的方法描述不清【即方法名一样 但是执行的内容不一致】直接上代码展示 然后写出解决方案 最后提出抽象的概念

之前我们在继承关系中 完全操作了成员变量 但是成员方法呢?

3.1 抽象类概述

举例: dog类和cat类都会吃 能不能把吃这个方法提取到父类animal中?

在这里插入图片描述

什么是抽象类

一种特殊的父类  里面可以写抽象方法

什么是抽象方法

当我们将共性方法提取到父类中之后,发现这个方法在父类中无法给出具体的描述【描述不清了】,而且这个方法还是子类中必须要有的方法

3.2 抽象类的定义格式

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类

抽象类和抽象方法必须使用 abstract 关键字修饰

访问修饰符 abstract 返回值类型 方法();
访问修饰符 abstract 返回值类型 方法();

注意事项:

1.抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

2.存在构造方法 —交给子类通过super进行访问的

3.抽象类不能实例化:无法通过new去创建自身的对象的【new 构造方法】 new 父类

4.抽象类的子类 —1.要么重写抽象类的所有方法 —2.要么也是一个抽象类

public abstract class TT {
    public abstract  void show();

    public static void main(String[] args) {
        TT tt = new TT() {
            @Override
            public void show() {
                
            }
        };
    }
}

3.3 abstract关键字冲突问题:

final:被abstract修饰的方法,强制要求重写子类,被final修饰的方法子类不能重写

private:被abstract修饰的方法,强制要求重写子类,被private修饰的方法子类不能重写

static:被static修饰的方法可以直接类名调用,类名调用抽象方法没有意义 两个关键字不能同时还出现

3.4 抽象类中总结成员特点

成员变量
可以是变量
也可以是常量
构造方法
有构造方法,但是不能实例化
那么,构造方法的作用是什么呢?用于子类访问父类数据的初始化
成员方法
可以有抽象方法:限定子类必须完成某些动作
也可以有非抽象方法:提高代码复用性

3.4 练习 猫和狗

需求:请采用抽象类的思想实现猫和狗的案例,并在测试类中进行测试
思路:
定义动物类(Animal)
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:get/set,吃();
定义猫类(Cat),继承动物类,重写吃的方法
构造方法:无参,带参
成员方法:吃(){…}
定义狗类(Dog),继承动物类,重写吃的方法
构造方法:无参,带参
成员方法:吃(){…}
定义测试类(AnimalDemo),写代码测试

4.接口

那我们在之前学完了抽象类 我们知道抽象类中 可以有抽象方法 也可以有非抽象的方法,可以有成员变量 也可以有常量。

那我们能不能抽取出来 在一个类中只定义抽象方法和常量。 让我们更加规范的使用。

在这里插入图片描述

在这里插入图片描述

4.1 接口概述

接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用

Java中的接口更多的体现在对行为(方法)的抽象

4.2 接口的特点

接口用关键字interface修饰

public interface 接口名 {
    public abstract 返回值类型 方法();
    …
}
注释: public abstract 可以省略
public interface Window {
    public abstract void show();
    public void show2();
    void show3();
}

类实现接口用implements表示

 1.public class 类名 implements 接口{
        重写方法;
    }
 2.创建一个抽象类 
public abstract class 类名 implements 接口{ //重写所需接口中的抽象方法}

接口不能实例化
接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态接口的实现类
要么重写接口中的所有抽象方法
要么是抽象类

4.3 接口的成员特点

为什么接口实现不能直接实例化【new出来】=>如果能new,就可以直接通过对象变量调用方法,毫无意义?

1.成员变量

只能是常量

默认修饰符:public static final

2.成员方法

只能是抽象方法

默认修饰符:public abstract

关于接口中的方法,JDK8和JDK9中有一些新特性 default,后面再讲解

3.构造方法

没有,因为接口主要是扩展功能的,而没有具体存在

一个类如果没有父类,默认继承自Object类

4.4 类和接口关系

类和类的关系

继承关系,只能单继承,但是可以多层继承

类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接

接口和接口的关系

继承关系,可以单继承,也可以多继承

4.5 抽象类和接口的区别

成员区别

抽象类 :变量,常量;有构造方法;有抽象方法,也有非抽象方法

接口 : 常量;抽象方法

关系区别

类与类 继承,单继承

类与接口 实现,可以单实现,也可以多实现

接口与接口 继承,单继承,多继承

设计理念区别

抽象类 对类抽象,包括属性、行为

接口 对行为抽象,主要是行为

接口是抽象类,但是抽象类不一定是接口!

抽象类在继承过程中占用extends关键字,耦合度高,不建议使用。建议使用接口!

4.6 应用和练习

我们先看一下抽象类的应用场景,再来对比一下接口的应用场景。

在这里插入图片描述

在这里插入图片描述

package com.gaohe.order;
public interface OrderInterface {
//    登录
    void log();
//    选择
    void choose();
//    购物车
    void gouwuche();
//    下单
    void xiadan();
//
    void pay();
//    结束
    void end();
}
package com.gaohe.order;

public class OrderClass implements OrderInterface{
    @Override
    public void log() {
        System.out.println("国内登录成功");
    }

    @Override
    public void choose() {
        System.out.println("国内选择");
    }

    @Override
    public void gouwuche() {
        System.out.println("国内加入购物车");
    }

    @Override
    public void xiadan() {
        System.out.println("国内下单");
    }

    @Override
    public void pay() {
        System.out.println("国内支付");
    }

    @Override
    public void end() {
        System.out.println("国内结束");
    }
}
package com.gaohe.order;

public class OrderWai implements OrderInterface{
    @Override
    public void log() {
        System.out.println("国外登录成功");
    }

    @Override
    public void choose() {
        System.out.println("国外选择");
    }

    @Override
    public void gouwuche() {
        System.out.println("国外加入购物车");
    }

    @Override
    public void xiadan() {
        System.out.println("国外下单");
    }

    @Override
    public void pay() {
        System.out.println("国外支付");
    }

    @Override
    public void end() {
        System.out.println("国外结束");
    }
    public void panduan(){
        System.out.println("判断网络结果为国外ip");
    }
}
package com.gaohe.order;

import java.util.Scanner;

public class OrderTest {
    public static void main(String[] args) {
        System.out.println("请选择版本 1代表国内 2代表国外");
        Scanner sc = new Scanner(System.in);
        int banben = sc.nextInt();
        OrderInterface o =null;
        if(banben == 1){
            o=new OrderClass();
        }else if(banben == 2){
            o=new OrderWai();
        }else{
            System.out.println("滚  ");
        }
//
//        o.panduan();
//        强制类型转化
//        if(banben == 2){
//            OrderWai o1 = (OrderWai) o;
//            o1.panduan();
//        }
        if(o instanceof OrderWai){
            OrderWai o1 = (OrderWai) o;
            o1.panduan();
        }
        o.log();
        o.choose();
        o.gouwuche();
        o.xiadan();
        o.pay();
        o.end();
/*
* OrderWai orderwai = new OrderWai();
            orderwai.log();
            orderwai.choose();
            orderwai.gouwuche();
            orderwai.xiadan();
            orderwai.pay();
            orderwai.end();
* */

    }
}

4.7 JDK8以后接口中新增的方法

在这里插入图片描述

接口的组成
1.常量

public static final

2.抽象方法

public abstract

默认方法(Java 8)
静态方法(Java 8)
私有方法(Java 9)(自行研究,仅在新版框架底层有所使用)

4.8 默认方法

接口中默认方法的定义格式:

格式:public default 返回值类型 方法名(参数列表) {   }

范例:public default void show1() { }

接口中默认方法的注意事项

public可以省略,default不能省略

4.9 静态方法

接口中静态方法的定义格式:

格式:public static 返回值类型 方法名(参数列表) {   }

范例:public static void show2() { }

接口中静态方法的注意事项

静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略

4.10 私有方法

接口中私有方法的定义格式:

格式1:private 返回值类型 方法名(参数列表) {   }

范例1:private void show3() { }

格式2:private static 返回值类型 方法名(参数列表) {   }

范例2:private static void show4() { }

接口中私有方法的注意事项

默认方法可以调用私有的静态方法和非静态方法
静态方法只能调用私有的静态方法

4.11 新接口方法应用场景

可以用做项目中的日志打印。

在这里插入图片描述
在这里插入图片描述

5.多态

引入:订单业务=>先写接口=>国内业务的实现类=>测试类的书写?思考新增国务业务应该怎么书写?

5.1 多态概述

多态:指的是同一个对象,在不同时刻表现出来的多种形态
举例:猫

5.2 多态的常见形式

多态的形式:具体类多态抽象类多态,接口多态

父类类型 对象名称 = new 子类构造器;
接口     对象名称 = new 实现类构造器;

我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同的时刻表现出来了多种形态,这就是多态

5.3 多态的前提和体现

1.有继承/实现关系
2.有方法重写
3.有父(类/接口)引用指向(子/实现)类对象

5.4 练习 猫和狗

需求:请采用多态的思想实现猫和狗的案例,并在测试类中进行测试
思路:
定义动物类(Animal)
成员变量:姓名,年龄
构造方法:无参,带参
成员方法:get/set,吃(){}
定义猫类(Cat),继承动物类,重写吃的方法
构造方法:无参,带参
成员方法:吃(){}
定义狗类(Dog),继承动物类,重写吃的方法
构造方法:无参,带参
成员方法:吃(){}
定义测试类(AnimalDemo),写代码测试

5.5 多态中成员访问特点

成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边

为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有

public class Animal {
    public String name = "动物";
    public void run(){
        System.out.println("动物跑得快");
    }
}
        public class Lion extends Animal{
            public  String name = "狮子";
            public int age = 18;
            public void run(){
                System.out.println("狮子跑得飞快");
            }
        }
public class Test {
    public static void main(String[] args) {
        Animal a = new Lion();
        System.out.println(a.name);
//        System.out.println(a.age);//报错了 ! 对变量 运行编译都看左边
        a.run();//狮子跑得飞快  编译看左边 运行看右边
    }
}

5.6 多态的好处和弊端

多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
多态的弊端:不能使用子类的特有功能

1.对象多态

好处:方法的形参定义为父亲类型,这个元素就可以接受该父类的任意子类对象了

2.行为多态

好处:同一个方法,具有多种不同的表现,或形态能力

public abstract class Animal {
    public abstract void eat();
}
public class Cat extends Animal{
    @Override
    public void eat(){
        System.out.println("吃猫粮");
    }
}
public class Dog extends Animal{
    @Override
    public void eat(){
        System.out.println("喜欢吃**");
    }
     public void lookDoor(){
        System.out.println("看门");
    }
}
public class AnimalOperator {
   // public void make(Dog dog){
   //     dog.eat();
   // }
   // public void make(Cat cat){
   //     cat.eat();
   // }
   public void make(Animal animal){
        animal.eat();
        //animal.lookdoor();

    }
}
public class Test {
    public static void main(String[] args) {
        AnimalOperator ao1 = new AnimalOperator();
        ao1.make(new Dog());
        AnimalOperator ao2 = new AnimalOperator();
        ao2.make(new Cat());
    }
}

5.7 多态中的转型

1.向上转型(自动转型)

从子到父

父类引用指向子类对象

2.向下转型(强制转型)

从父到子

父类引用转为子类对象

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
    	//向上转型 
        Animal a = new Lion();// 
        System.out.println(a.name);
        a.run();//狮子跑得飞快 
        //向下转型
       // Lion lion =  (Lion) a;
       // lion.attack();
        Tiger tiger =  (Tiger) a;//java.lang.ClassCastException
        tiger.attack();
    }
}

5.8 多态中的转型问题

概述:如果被转型的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException
解决方法
关键字:instanceof
使用格式:
对象名 instanceof 类型
判断一个对象是否是一个类的实例
通俗理解:判断关键字的左边的对象,是否是右边的类型,返回boolean类型结果

		{
		Animal a1 = new Dog();//自动类型转换  父类类型 对象名 = new 子类构造器();
        Animal a2 = new Pig();
        check(a1);
        check(a2);
        }
        
//将要判断的内容提到一个静态方法中  方便调用 提高了代码的复用效率
    public static void check(Animal animal){
        if (animal instanceof Dog){//
            Dog dog1 = (Dog) animal;
            dog1.lookDoor();
        }else if (animal instanceof Pig){
            Pig pig1 = (Pig) animal;
            pig1.sleep();
        }
    }

5.9 案例

在这里插入图片描述

public interface Pay {
    public abstract void pay(double money);
}
public class ZhiFuPingTai implements Pay{
    @Override
    public void pay(double money) {
        System.out.println("通过支付平台支付"+ money);
    }
}
public class BankCard implements Pay{
    @Override
    public void pay(double money) {
        System.out.println("通过银行卡支付了" + money);
    }
}
public class XinYongKa implements  Pay{
    @Override
    public void pay(double money) {
        System.out.println("通过信用卡支付"+ money);
    }
}
public class Test01 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请选择支付方式1.支付平台支付2.银行卡支付3.信用卡支付");
        System.out.println("请选择支付方式:");
        int i = sc.nextInt();
        System.out.println("请选择支付金额:");
        double money = sc.nextDouble();
        Pay pay = null;
        if (i== 1){
             pay = new ZhiFuPingTai();
             pay.pay(money);
        }else if(i == 2){
            pay = new BankCard();
            pay.pay(money);
        }else if(i ==3){
            pay = new XinYongKa();
            pay.pay(money);
        }
    }
}

6.代码块

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值