Java子类构造函数中访问父类的私有属性

huangapple go评论59阅读模式
英文:

Java parent's private attribute inside child constructor

问题

以下是翻译好的内容:

标题已经说明了一切,我有一个类,构造函数的变量必须是私有的。

public class AdMedia {
    private String name;
    private int price;
    
    public AdMedia() {}
    
    public AdMedia(String name, int price) {
        this.name = name;
        this.price = price;
    }
}

当然,它附带了变量的公共 gettersetter

现在的问题出现在我尝试创建一个名为 Magazine 的子类之后。这个类应该继承名称和价格,但是价格对于每个对象的初始化都是恒定的,所以它们不会像名称一样出现在构造函数中。

public class Magazine extends AdMedia {
    private int area;
    private String position;
    private String topics;
    
    public Magazine() {}
    
    public Magazine(String name, int size, String position, String topic) {
        super();
        this.size = size;
        this.position = position;
        this.topic = topic;
    }
}

这个类也有它自己的 gettersetter

我尝试将价格放在构造函数中,但构造函数要求传递参数。使用 super(name) 也提示父构造函数没有这样的形式。

当我试图使用父类方法 getName() 来获取 name 时,这让我很复杂,可能需要一些向下转型吧?

我尝试搜索解决方案,但大多数要求我将变量的访问权限更改为 protected。难道没有其他方法可以在 private 的情况下做到吗?

编辑:
我忘记提到通过上述方法的结果是无法访问 Magazine 的名称,所以当我尝试进行向下转型并获取名称时,返回的是 null。

英文:

The title says it all, I got a class in which the variables of the constructor must be private.

public class AdMedia {
private String name;
private int price;

public AdMedia(){}


public AdMedia(String name, int price) {
	this.name = name;
	this.price = price;
}

that comes with public getter setter of the variables of course.

Now the problem comes right after I try to make a child class named Magazine. The class should inherit the name and price but the price is constant for every object initiation. so they won't be on the constructor as the name.

public class Magazine extends AdMedia {
private int area;
private String position;
private String topics;

public Magazine() {}
public Magazine(String name, int size, String position, String topic){

	super();
	this.size = size;
	this.position = position;
	this.topic = topic;
	
}

that also comes with its own getter setter too.

I try to put the price inside the constructor but the constructor demand a passed parameter. Using super(name) also notifies that none of parent constructor have such shape.

This complicates me when I'm trying to get the name using parent class method getName() which might require some downcasting I guess?

I had try to search for the solution but most require me to change the variable's accessibility into protected . Would there be no other way to do it in private ?

EDIT :
I forgot to mention that the result by doing what I wrote above is the unability to access Magazine name, so when I try to downcast-get the name, what returned is a null.

答案1

得分: 4

你可以将子构造函数编写为:

public Magazine(String name, int size, String position, String topic){
    super();
    setName(name);
    setPrice(100); // 100是您的固定价格
    this.size = size;
    this.position = position;
    this.topic = topic;
}

或者为:

public Magazine(String name, int size, String position, String topic){
    super(name, 100); // 100是您的固定价格
    this.size = size;
    this.position = position;
    this.topic = topic;
}

然而,两种方式都会打开稍后更改价格的可能性:

Magazine m = new Magazine("name", 50, "position", "topic");
m.setPrice(10);

如果您需要阻止这种情况,您还应该重写 setPrice() 设置器:

public class Magazine extends AdMedia {

    ...
    @Override
    public void setPrice(int price) {
        // 在这里应该做什么?
        // * 您可以选择静默忽略
        //   (这可能会让某些用户感到惊讶,因为他们希望能够更改价格)
        // * 抛出 UnsupportedOperationException
        //   (这可能会让其他用户感到惊讶,他们未准备处理这样的异常)
    }
}
英文:

You could write your child constructor either as

public Magazine(String name, int size, String position, String topic){
    super();
    setName(name);
    setPrice(100); // 100 is your constant price
    this.size = size;
    this.position = position;
    this.topic = topic;
}

or as

public Magazine(String name, int size, String position, String topic){
    super(name, 100); // 100 is your constant price
    this.size = size;
    this.position = position;
    this.topic = topic;
}

Both ways would however open the possibility to change the price later:

Magazine m = new Magazine("name", 50, "position", "topic");
m.setPrice(10);

If you need to prevent this, you should also override the setPrice() setter:

public class Magazine extends AdMedia {

    ...
    @Override
    public void setPrice(int price) {
        // what to do here?
        // * you could either silently ignore 
        //   (which might surprise some users expecting to be able to change the price)
        // * throw an UnsupportedOperationException 
        //   (which might surprise other users which are not prepared to handle such an exception)
    }
}

huangapple
  • 本文由 发表于 2020年5月30日 00:35:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/62090651.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定