【问题标题】:base and subclass constructor issues基类和子类构造函数问题
【发布时间】:2010-12-31 04:36:32
【问题描述】:

过去几天我一直在尝试使用 Java 中的类,从 youtube 上的“TheNewBoston”和 java 文档中了解它们。

我创建了以下场景,并就我的一些问题寻求你们的男人(女孩)的专业批评和深入了解。

有两个类,person和person_financial,分别是基类和子类。

人物类:

public class person {

private String name;
private String sex;
private int age;
private double height;
private double weight;
private double intelligence;

// person constructor arguments order: name, height, weight, age, sex, intelligence
public person(){
    this("noname",0,0,0,"undefined",5);
}
public person(String n){
    this(n,0,0,0,"undefined",5);
}
public person(String n, double h){
    this(n,h,0,0,"undefined",5);
}
public person(String n, double h, double w){
    this(n,h,w,0,"undefined",5);
}
public person(String n, double h, double w, int a){
    this(n,h,w,a,"undefined",5);
}
public person(String n, double h, double w, int a, String s){
    this(n, h, w, a, filterSex(s), 5);
}
public person(String n, double h, double w, int a, String s, double i){
    name = n;
    height = h;
    weight = w;
    age = a;
    sex = filterSex(s);
    intelligence = i;
}

public void setName(String n){
    name = n;
}
public void setHeight(double h){
    height = h;
}
public void setWeight(double w){
    weight = w;
}
public void setAge(int a){
    age = a;
}
public void setSex(String s){
    sex = filterSex(s);
}
public void setIntel(double i){
    intelligence = i;
}

public String getName(){
    return name;
}
public double getHeight(){
    return height;
}
public double getWeight(){
    return weight;
}
public int getAge(){
    return age;
}
public String getSex(){
    return sex;
}
public double getIntel(){
    return intelligence;
}

public String getInfo(){
    return String.format("Name: %s,\nSex: %s,\nAge: %d,\nIntelligence: %.2f,"
            + "\nHeight: %.2f,\nWeight: %.2f\n", name, sex, age,
            intelligence, height, weight);
}

private static String filterSex(String s){
    return ((s.equalsIgnoreCase("male") ||
             s.equalsIgnoreCase("female")) ? s : "undefined");
}
}

person_financial 类:

public class person_financial extends person {

private double monies = 0;

public void definePerson(String n, int a, String s, double i, double h, double w){
    setName(n);
    setAge(a);
    setSex(s);
    setIntel(i);
    setHeight(h);
    setWeight(w);
}

public person_financial() {
    this(0);
}

public person_financial(double m) {
    monies = m;
}

public void depositMonies(double m) {
    monies += m;
}

public void withdrawlMonies(double m) {
    if (m <= monies) {
        monies -= m;
    }
}

public double getBalance() {
    return monies;
}
}

然后在主课中我有这个:

public class Main {

public static void main(String[] args) {

    person p1 = new person("I have no Name", 180, 72, 38, "Alien", 7.2);
    System.out.println(p1.getName());


    person_financial pf1 = new person_financial(100.00);
    pf1.depositMonies(50.02);
    System.out.printf("%s has %.2f monies.\n", pf1.getName(), pf1.getBalance());

    pf1.definePerson("some_name", 42, "male", 10, 180, 72);
    System.out.println(pf1.getInfo());
}
}

在 person_financial 类中,我创建了一个名为“definePerson()”的方法,我用它来定义所有本来可以从“person”类的“person()”构造函数中定义的特征。我确信有一种更专业的方法可以从子类为基类中的变量赋值,我只是不知道...

另外,有没有办法从“person”类调用构造函数来定义“pf1”的特征?例如,不必手动设置每个属性,即 pf1.setName("something"); , 或 pf1.setAge(1000000);等等......或者有一个方法为我做,就像'definePerson()'。

非常感谢任何帮助, 谢谢 =)。

【问题讨论】:

    标签: java class constructor


    【解决方案1】:

    您使用super() 调用来调用父类的构造函数。它必须是派生类的构造函数中的第一个调用,但你调用它(并传入参数)就像任何其他函数一样,它会以这种方式调用构造函数。

    【讨论】:

    • 谢谢!我在子类的构造函数中添加了“super()”,一切都如我所愿!
    【解决方案2】:

    声明一个“抽象”类以防止创建通用对象是很常见的——根据底部的使用代码,你似乎不希望这样,这很好。请记住,您可以声明一个类抽象。

    使用类层次结构的最好方法是确保(流行语警告)有用层次结构中的任何类都应该可以声明为层次结构中的任何类(即,您应该能够从基础访问具体对象中的任何方法-类(在这种情况下是人)。

    您的 Financial_person 对象扩展了 person,但理想的情况是拥有一个可以在较高级别声明并以多态方式调用方法的类。请考虑一下所有人都可以取款和存款的情况(与您的班级不同,但请耐心等待一分钟)。

    drawMoney 方法将存在于 person,但被标记为抽象 - 强制子类 Financial_person 和 regular_person 实现 draw_money、deposit_money 等。

    每个类都有一个适合其实际情况的实现(财务人员可以访问各种特殊帐户、折扣等,而 regular_person 将有一组更简单的 - 但仍然是相同的外部行为)。

    那么你可以这样声明:

    Person finPerson = new FinancialPerson(... etc.);
    Person regPerson = new RegularPerson(....etc);
    

    现在请注意,您可以在下面执行此代码:

    finPerson.drawCash(12300.0);
    regperson.drawCase(100.0);
    

    相同的行为。

    您可以拥有一个包含数千人的列表,而不必执行 if-then-else 或 switch 语句来执行每个人的微调行为。

    对类层次结构的严格测试是这样的:“我的(子类)真的是‘一种’(超类)吗?”

    换句话说,“我的子类有超类的行为吗?”

    如果不是,您应该仔细考虑类层次结构。有一个流行词:里氏替换原则,我不能比罗伯特做得更好。 C. Martin - 软件设计大师之一:

    http://www.objectmentor.com/resources/articles/lsp.pdf

    在这篇文章中,他使用“正方形是一种矩形”的例子展示了当你有不明智的层次结构时会发生什么。

    谷歌“模板方法模式”总结了有效使用继承的另一个方面。你会发现它比大多数人认为的简单继承要强大得多。

    还请记住,没有一种单一的模式是万能的。有些人会称类层次结构为邪恶,并告诉您只使用接口;其他人会说相反。有一些选择要做出,有时它们并不明显。

    有很多陷阱,缺少 LSP 只是其中之一。其他(仅示例)覆盖具体方法,具有未标记为最终的具体类,启用“识别”字段的可变性(例如,equals/hashcode中使用的字段等)想象如果银行的“客户”对象允许重置名字,或运行时的帐号,一旦这些字段已设置)。

    我的回答更一般地与 OO 设计、继承等有关,而不是具体的编码问题——希望它对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      相关资源
      最近更新 更多