Java中面向对象编程(OOP)

关于Java中面向对象编程(OOP)中的继承、多态和封装的基本概念

父类

import com.renting_house.HouseTool;
​
import java.util.Scanner;
​
​
/*
相关的业务层
*/
public class HouseService {
​
​
    // 数组用来存储其输入的信息,先动态创建数组,不分配空间大小
    String[] arr;
    int count; // 用来统计房屋的空间大小的
​
    // 变量值
    private boolean variabel;
    private String key;
    // 新增房源的相关信息
    private String name;
    private String phone;
    private String address;
    private double MonthlyRent;
    private String state;
​
    Scanner sc = new Scanner(System.in);
​
    public HouseService(String key) {
        this.setKey(key);
​
​
    }
​
​
    // set以及get
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getPhone() {
        return phone;
    }
​
    public void setPhone(String phone) {
        this.phone = phone;
    }
​
    public String getAddress() {
        return address;
    }
​
    public void setAddress(String address) {
        this.address = address;
    }
​
    public double getMonthlyRent() {
        return MonthlyRent;
    }
​
    public void setMonthlyRent(double monthlyRent) {
        MonthlyRent = monthlyRent;
    }
​
    public String getState() {
        return state;
    }
​
    public void setState(String state) {
        this.state = state;
    }
​
    public String getKey() {
        return key;
    }
​
    public void setKey(String key) {
        this.key = key;
    }
​
    public boolean getVariabel() {
        return variabel; // 布尔值的返回类型是true或者false。 固定的不可以进行赋值
    }
​
    public void setVariabel(boolean variabel) {
        this.variabel = variabel;
    }
​
    // 新增房源的方法
    public void AddHouse() {
        // 创建工具类对象
        HouseTool houseTool = new HouseTool(getKey());
​
        int i = 0;
        System.out.println("请输入添加房屋的数量:");
        count = sc.nextInt();
        sc.nextLine();
        System.out.println("如果数量添加错误请输入 : n");
        key = sc.nextLine();
        if (key.equals("n")) {
            count = 0;
            System.out.println("请重新输入添加房屋的数量:");
            count = sc.nextInt();
            sc.nextLine();
        }
​
        key = null;
​
        do {
            arr = new String[count];
            System.out.println("------------------请输入你的选择--------------------");
            System.out.print("姓名:");
            name = sc.nextLine();
            System.out.print("电话:");
            phone = sc.nextLine();
            System.out.print("地址:");
            address = sc.nextLine();
            System.out.print("月租:");
            MonthlyRent = sc.nextDouble();
            sc.nextLine();  // 这是清楚掉nextInt();遗留的换行符
            System.out.print("状态:");
            state = sc.nextLine();
            System.out.println("------------------添加完成--------------------");
​
            if (i < arr.length) {
                arr[i] = name + "\t" + phone + "\t" + address + "\t" + MonthlyRent + "\t" + state;
            }
​
            // 这里的接受有问题。没有接受到 。 不要在这里使用,
​
// System.out.println(“是否要继续添加 : y/n”);
// setKey(key = sc.nextLine());
// System.out.println(getKey());
​
​
            houseTool.judgement();
​
​
        } while (getVariabel());
​
        for (String value : arr) {
            if (value == null) {
                System.out.println(" ");
            }
            System.out.println(value);
        }
        System.out.println("-----------------------------");
        System.out.println(getKey());
        System.out.println(getVariabel());
​
    }
​
    public static void main(String[] args) {
        HouseService houseService = new HouseService("null");
        houseService.AddHouse();
    }
}

子类

/*
工具类
*/
public class HouseTool extends HouseService {
​
​
public HouseTool(String key) {
    super(key);
}
​
// 用于添加出租屋中的逻辑判断
public void judgement() {
    System.out.println("是否要继续添加 : y/n");
    setKey(sc.nextLine());
    System.out.println(getKey());
​
    do {
        if (getKey().equals("n")) {
            System.out.println(getKey());
            setVariabel(false);
            System.out.println(getVariabel());
            break;
        }
​
        if (getKey().equals("y")) {
            System.out.println(getKey());
            setVariabel(true);
            System.out.println(getVariabel());
            break;
​
        } else {
            System.out.println("未检测到有效的指令");
            System.out.println("是否要继续添加 : y/n");
            setKey(sc.nextLine());
        }
    } while (true);
​
​
}

输出

true 子类是true
x qe wsfc 100.0 zfc
null
null
null
​
null
false 在父类中,为什么依旧是false

疑问

true 子类是true 但是 false 在父类中,为什么依旧是false

回答

  • 尝试在 HouseService 类(即父类)中使用 getVariabel() 时,会返回默认值(通常是 false 或未初始化状态),因为在父类中并没有这样的方法或变量。如果想让父类也能够访问并修改这个布尔变量,需要在父类中也定义相应的 getter 和 setter 方法,或者将这个布尔变量设为 protected 让子类可以访问,然后在 judgement() 方法中直接通过父类引用来操作这个变量。

在父类中也定义相应的 getter 和 setter 方法

  • 对象状态与实例变量: 在Java中,对象的状态是由其类中的实例变量(也称为字段)所决定的。当一个类继承自另一个类时,子类继承了父类的所有非私有(non-private)方法和变量(包括保护的protected和默认的包级别访问权限的变量)。但是,继承并不意味着子类对象与父类对象共享同一个实例变量;相反,每个对象实例都有自己的一套实例变量副本。

  • 方法覆盖(Overriding)与实例变量: 在您的例子中,您并没有覆盖任何方法(除非HouseService类中有一些未在代码中显示的方法被您重写了)。但更重要的是,实例变量的值是由具体对象实例的状态所决定的,而不是由类的继承关系决定的。因此,无论您在子类还是在父类中访问一个实例变量,您都将得到与当前对象实例相关的值。

  • 当前对象的实例相关值。这和很重要,这也是为什么,true 子类是true 但是 false 在父类中,为什么依旧是false。尽管继承了。但是在不同对象里面,等到的都是当前对象实例相关的值

更加准确的解释是

  • 如果父类有一个实例变量,并且您在父类对象中将其设置为false,在子类对象中将其设置为true(假设子类没有隐藏这个变量),那么这两个对象将分别拥有falsetrue的值,因为它们是两个完全不同的对象实例

    重要的是要理解,即使子类继承了父类,子类对象中的实例变量值也不会影响父类对象中的实例变量值,因为它们是独立的对象实例。

  • 一个更准确的表述可能是:“尽管子类继承了父类,但子类对象和父类对象中的实例变量值仍然是各自独立的,由各自对象实例的状态决定。

解决

  • 正如上述表述

  • 尽管子类继承了父类,但子类对象和父类对象中的实例变量值仍然是各自独立的,由各自对象实例的状态决定。

  • 可以通过在父类中调用子类的相关函数。并且将其赋值给父类的变量

  • 代码 :子类 。

    public boolean judgement() {
    ​
            do {
                System.out.println("是否要继续添加 : y/n");
                setKey(key = scanner.nextLine());
                System.out.println(getKey());
    ​
                // 这里我们实际上不需要一个 do-while 循环,因为只需要读取一次输入
                if ("n".equals(key)) {
                    return false;
                }
    ​
                if ("y".equals(key)) {
                    return true;
                } else  {
                    System.out.println("未检测到有效的指令");
                }
    ​
    ​
            }while (true);
        }
  • 代码 :父类

     do {
                arr = new String[count];
                System.out.println("------------------请输入你的选择--------------------");
                System.out.print("姓名:");
                name = scanner.nextLine();
                System.out.print("电话:");
                phone = scanner.nextLine();
                System.out.print("地址:");
                address = scanner.nextLine();
                System.out.print("月租:");
                MonthlyRent = scanner.nextDouble();
                scanner.nextLine();  // 这是清楚掉nextInt();遗留的换行符
                System.out.print("状态:");
                state = scanner.nextLine();
                System.out.println("------------------添加完成--------------------");
    ​
                if (i < arr.length) {
                    arr[i] = name + "\t" + phone + "\t" + address + "\t" + MonthlyRent + "\t" + state;
                }
    ​
                variabel = houseTool.judgement(); 
    ​
            } while (variabel);
  • 如上述代码的显示;父类中调用子类的相关函数。并且将其赋值给父类的一共变量。(这样就子类和父类的布尔值就是一样的)

  • 注意:直接在父类中调用子类的方法通常不是一个好的设计,因为它违反了面向对象设计中的一个基本原则:封装和抽象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值