Java扩展类和设置值

Java扩展类和设置值,java,oop,extend,Java,Oop,Extend,动物基类 public class Animal { protected String pig; protected String dog; protected String cat; public void setPig(String pig_) { pig=pig_; } public void setCat(String cat_) { cat=cat_; } public void setDog(String dog_) { dog=dog_; } } 动物活动类 p

动物基类

public class Animal
{

protected String pig;
protected String dog;
protected String cat;

public void setPig(String pig_)
{
  pig=pig_;
}
public void setCat(String cat_)
{
  cat=cat_;
}
public void setDog(String dog_)
{
  dog=dog_;
}

}
动物活动类

public class AnimalAction extends Animal
{
  public AnimalAction(String pig, String cat, String dog)
  {
       super.pig = pig;
       super.cat = cat;
       super.dog = dog;
  }

}

这是设置受保护变量的正确方法吗?使用受保护变量是正确的方法吗?有更专业的OO方法吗?

您应该能够使用
this.pig
等,因为您继承了受保护的成员。实际上,您也可以调用
公共setPig(…)
方法。

无需使用
super
前缀或任何其他前缀来访问受保护的变量

顺便说一句——有一点我不同意托马斯的观点——不要在构造函数中调用超类的setter方法。如果子类重写了构造函数中的非最终设置器,那么在构造函数中使用非最终设置器可能会产生不好的效果。然后可以对未完全构造的对象调用它们。但是你应该考虑让你的设定者是最终的,如果你不意味着他们被重写。


Joshua Bloch在中解释了“设计继承或禁止继承”的原则。

使用受保护的成员变量,然后在子类中继承它们,没有什么错

但是,如果一个开发人员出现并对您的类进行子类化,他们可能会把它搞砸,因为他们不完全理解它。对于私有成员,除了公共接口之外,他们看不到具体实现的细节,也看不到如何进行操作,这给了您以后更改的灵活性。
通过提供
受保护的成员变量
您只是在子类和超类之间紧密耦合。

您可以使用私有变量而不是受保护的变量。这会更合适。 可以使用构造函数设置超类的值。 编辑:


在类外看到的成员变量越少越好。我会将类变量设置为private,并将getter设置为public(或根据需要设置为public)和setter设置为protected。

您的示例非常混乱,但它会起作用。我再举一个例子:

//类/接口/枚举使用大写字母,方法/字段使用小写字母

public class Animal 
{
protected String name;
protected int numberOfFeet;

public Animal(String name)
{
    this.name = name;
}

public void setNumberOfFeet(int numberOfFeet)
{
    this.numberOfFeet = numberOfFeet;
}
}

public class Dog extends Animal
{
    public Dog()
    {
        super("dog"); // call the constructor of the super class.

        // because Dog extends Animal and numberOfFeet is protected, numberOfFeet becomes part of "this" class.
        this.numberOfFeet = 4;
    }
}

//Now you can create instances of Animal like:
Animal bird = new Animal("bird");
bird.setNumberOfFeet(2);
//Or use Dog to create an animal "dog" with 4 feet.
Animal dog = new Dog();

//after an accident
dog.setNumberOfFeet(3);

为什么你有setter但没有使用它们?请将你的类大写。这是Java中的标准。@如果子类重写非最终设置器,则在构造函数中使用非最终设置器的Poindexter可能会产生难看的效果。问题应该是“为什么你的二传手不是最终的?”@kostja这是我想要的讨论类型。我需要有人给我指出正确的方法谢谢托马斯,这个整体方法看起来正确吗?它会起作用,但不是一个好方法。在这里的其他答案中有几种更正确的方法。
public class Animal 
{
protected String name;
protected int numberOfFeet;

public Animal(String name)
{
    this.name = name;
}

public void setNumberOfFeet(int numberOfFeet)
{
    this.numberOfFeet = numberOfFeet;
}
}

public class Dog extends Animal
{
    public Dog()
    {
        super("dog"); // call the constructor of the super class.

        // because Dog extends Animal and numberOfFeet is protected, numberOfFeet becomes part of "this" class.
        this.numberOfFeet = 4;
    }
}

//Now you can create instances of Animal like:
Animal bird = new Animal("bird");
bird.setNumberOfFeet(2);
//Or use Dog to create an animal "dog" with 4 feet.
Animal dog = new Dog();

//after an accident
dog.setNumberOfFeet(3);