JAVA_面向对象_继承

  1. 继承

    在继承的关系中,子类就是一个父类,也就是说,子类可以被当做父类看待

    例如:父类是员工,子类是程序员,那么程序员就是一个员工

    // 员工类
    public class Employee{
        String name;
        int age;
    }
    
    // 程序员类(继承员工类)
    public class Programer extends Employee{
    } 
    
    // 主方法
    public class Extends {
        public static void main(String[] args) {
            Programer coder = new Programer();
            coder.name = "johny";
            coder.age = 20;
            System.out.println(coder.name + " " + coder.age);  // johny 20
        }
    }
    

    在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:
    1. 直接通过子类对象访问成员变量:(优先使用自己的,没有则向上找)
    2. 间接通过成员方法访问成员变量:(看方法属于谁,就优先用谁的,没有则往上找,找不到就报错)

    在父子类的继承关系中,创建子类对象,访问成员方法的规则:
    1. 创建的对象是谁,就优先用谁,如果没有就向上找

    无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的

  2. 区分子类方法中重名的三种变量
    1. 局部变量: 直接写成员变量名
    2. 本类中的成员变量: this.成员变量名
    3. 父类中的成员变量: super.成员变量名
  3. 继承中方法的覆盖

    覆盖与方法的重载不同:同样是方法名相同,但覆盖指接收的参数也相同

    注意事项:

    1. 在子类方法前面写上@Override,用来检测是不是有效的正确覆盖重写

    2. 子类方法的返回值必须小于等于父类方法的返回值范围(例如:子类返回String,父类返回Object)

    3. 子类方法的权限必须大于等于父类方法的权限修饰符

      public > protected > (default) > private

    // 父类
    public class Phone {
        public void call(){
            System.out.println("call");
        }
    
        public void send(){
            System.out.println("send");
        }
    }
    
    // 子类
    public class NewPhone extends Phone{
        // 方法权限必须大于等于父类
        public void call(){
            // 调用父类方法
            super.call();
            // 添加自己的逻辑
            System.out.println("show picture");
        }
    }
    
    public class DemoCover {
        public static void main(String[] args) {
            NewPhone newPhone = new NewPhone();
            newPhone.call();  // call \n show picture
        }
    }
    
  4. 继承中构造方法的访问特点

    Notice:

    1. 子类构造方法中有一个默认隐含的 “super()” 调用,所以一定是先调用的父类构造,再调用的子类构造
    2. 子类构造可以通过 “super” 关键字来调用父类的重载构造(当父类含有多个构造方法)
    3. super 的父类构造方法调用,必须是子类构造方法的第一条语句,且只能调用一次 super 构造

    sum up:子类必须调用父类的构造方法,不写则赠送 super() ,写了就调用指定的 super 。

  5. super 关键字的三种用法
    1. 在子类的成员方法中,使用 super 得到父类的成员变量
    2. 在子类的成员方法中,使用 super 访问父类的成员方法
    3. 在子类的构造方法中,使用 super 访问父类的构造方法
  6. this 关键字的三种用法

    super 关键字用来访问父类内容,而 this 关键字用来访问本类内容

    1. 在本类的成员方法中,使用 this 得到本类中的成员变量

    2. 在本类的成员方法中,使用 this 访问本类中的成员方法

    3. 在本类的构造方法中,使用 this 调用本类的重载构造方法(另一个构造方法)

      this(…) 调用也必须是构造方法中的第一条语句,且只能使用一次

      super 和 this 两种构造使用,不能同时使用

  7. this 和 super 关键字图解在这里插入图片描述
  8. 继承的三个特点图解在这里插入图片描述
  9. 抽象方法和抽象类

    抽象方法:就是在 void 前面加上 abstract 关键字,然后去掉大括号,直接分号结束

    抽象类:抽象方法所在的类,必须是抽象类,在 class 前面加上 abstract 关键字即可

    // 这是一个抽象类
    public abstract class Animal{
        // 这是一个抽象方法,代表吃东西,具体吃什么?不知道
        public abstract void eat();
    }
    

    如何使用抽象类和抽象方法?

    1. 不能直接 new 抽象类,必须使用子类继承抽象父类
    2. 非抽象子类必须覆盖抽象父类的所有的抽象方法
    3. 创建非抽象子类对象进行使用

    Notice:

    1. 抽象类中,可以有构造方法,是供非抽象子类创建对象时,初始化父类成员使用的
    2. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类
    // 抽象父类
    public abstract class Animal{
        public Animal(){
            System.out.println("抽象父类构造方法执行");
        }
        // 抽象方法
        public abstract void eat();
        public abstract void sleep();
    }
    
    // 抽象子类
    public abstract class Dog extends Animal{
        @Override
        public void eat(){
            System.out.println("dog eat meat");
        }
    }
    
    // 间接子类
    public class JinMao extends Dog {
        @Override
        public void sleep(){
            System.out.println("JinMao in his sleeping");
        }
    }
    public class HaShiQi extends Dog {
        @Override
        public void sleep(){
            System.out.println("HaShiQi in his sleeping");
        }
    }
    
    public class DemoAbstract{
        public static void main(String[] args){
            JinMao jinMao = new JinMao();
            jinMao.eat();
            jinMao.sleep();
    
            HaShiQi haShiQi = new HaShiQi();
            haShiQi.eat();
            haShiQi.sleep();
        }
    }
    
    // 执行结果
    抽象父类构造方法执行
    dog eat meat
    JinMao in his sleeping
    抽象父类构造方法执行
    dog eat meat
    HaShiQi in his sleeping
    
  10. 发红包案例
// User基类
public class User {
    private String name;
    private int money;

    public User(){
    }
    public User(String name, int money){
        this.name = name;
        this.money = money;
    }

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }

    public void setMoney(int money){
        this.money = money;
    }
    public int getMoney(){
        return this.money;
    }

    public void show(){
        String str = String.format("my name is %s, i have %d yuan ", this.name, this.money);
        System.out.println(str);
    }
}
// 群主类
import java.util.ArrayList;
import java.util.Scanner;

public class Manager extends User{

    public Manager(){
    }
    public Manager(String name, int money){
        super(name, money);
    }

    // 发红包
    public ArrayList<Integer> send(){
        while (true){
            // 确定发多少钱,发多少个?
            Scanner scanner = new Scanner(System.in);
            int money = scanner.nextInt();
            int count = scanner.nextInt();
            if (money > super.getMoney()) {
                String str = String.format("your balance is %d! place re-select", super.getMoney());
                System.out.println(str);
                continue;
            }
                // 确定每个红包有多少钱
                int avg = money / count;
                int remainder = money % count;  // 余数,就是零头

                // 塞钱进红包, 使用集合表示红包
                ArrayList<Integer> set = new ArrayList<>();
                for (int i = 0; i < count - 1; i++) {
                    set.add(avg);
                }
                // 把零头塞进最后一个红包里面
                set.add(avg + remainder);
                // 减去余额
                super.setMoney(super.getMoney() - money);
                return set;
        }
    }
}
// 成员类
import java.util.ArrayList;
import java.util.Random;

public class Member extends User{

    public Member(){
    }
    public Member(String name, int money){
        super(name, money);
    }

    // 收红包
    public void receive(ArrayList<Integer> set){
        // 随机收一个红包
        Random random = new Random();
        int index = random.nextInt(set.size());
        int cash = set.remove(index);
        String str = String.format("i got was %d yuan", cash);
        System.out.println(str);
        // 修改余额
        super.setMoney(super.getMoney() + cash);
    }
}
// 程序运行入口
import java.util.ArrayList;

public class DemoStart {
    public static void main(String[] args){
        // 建群,拉人
        Manager manager = new Manager("Manager", 100);
        Member mbA = new Member("mbA", 0);
        Member mbB = new Member("mbB", 0);
        Member mbC = new Member("mbC", 0);
        manager.show();
        mbA.show();
        mbB.show();
        mbC.show();

        // 发红包
        ArrayList<Integer> set = manager.send();

        // 收红包
        mbA.receive(set);
        mbB.receive(set);
        mbC.receive(set);

        // 活动结束后各自有多少钱?
        manager.show();
        mbA.show();
        mbB.show();
        mbC.show();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值