Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写抽象字段_Java_Oop_Abstract Class_Encapsulation - Fatal编程技术网

Java 重写抽象字段

Java 重写抽象字段,java,oop,abstract-class,encapsulation,Java,Oop,Abstract Class,Encapsulation,我有一个抽象类,它有一个扩展该类的所有类都使用的方法。每个类的方法都是相同的,所以我不想在这些类中反复编写。问题是该方法使用了在每个类中声明的2个变量。如果抽象类中没有这些变量,我就不能在抽象类中使用该方法。但如果我这样做,它们将接受抽象类中指定的值,而不是扩展它的类。我怎样才能解决这个问题 示例代码: public abstract class Example { public String property1 = "" public String property2 = ""

我有一个抽象类,它有一个扩展该类的所有类都使用的方法。每个类的方法都是相同的,所以我不想在这些类中反复编写。问题是该方法使用了在每个类中声明的2个变量。如果抽象类中没有这些变量,我就不能在抽象类中使用该方法。但如果我这样做,它们将接受抽象类中指定的值,而不是扩展它的类。我怎样才能解决这个问题

示例代码:

public abstract class Example {
   public String property1 = ""
   public String property2 = ""
    public ArrayList<String> getPropertyies() {
        ArrayList<String> propertyList = new ArrayList<>();
        propertyList.add(property1);
        propertyList.add(property2);
        return property1;
    }
}

public class ExampleExtension extends Example {
    public String property1 = "this is the property";
    public String property2 = "this is the second property";
}
公共抽象类示例{
公共字符串property1=“”
公共字符串property2=“”
公共阵列列表getPropertyies(){
ArrayList propertyList=新的ArrayList();
添加(property1);
propertyList.add(property2);
归还财产1;
}
}
公共类ExampleExtension扩展示例{
公共字符串property1=“这是属性”;
公共字符串property2=“这是第二个属性”;
}

您不必重写变量。您可以在构造函数中设置属性的初始值:

public class ExampleExtension extends Example {

    public ExampleExtension() {
        property1 = "this is the property";
        property2 = "this is the second property";
    }

}
public class ExampleExtension extends Example {

    public ExampleExtension() {
        super("value1", "value2");
        // initialize private fields of ExampleExtension, if any
    }
    // ...
}

更好的方法是使用带参数的构造函数,正如Mick Mnemonic在另一个答案中所建议的那样

IMO Mick的解决方案是最实用的,不过请注意,您也可以选择将属性抽象化,然后使用子类多态性要求子类重写属性实现:

public abstract class Example {
   public abstract String getProperty1();
   public abstract String getProperty2();

    public ArrayList<String> getPropertyies() {
        ArrayList<String> propertyList = new ArrayList<>();
        propertyList.add(getProperty1());
        propertyList.add(getProperty2());
        return propertyList;
    }
}

public class ExampleExtension extends Example {
    public String getProperty1() { return "this is the property"};
    public String getProperty2() { return "this is the second property"};
}
公共抽象类示例{
公共抽象字符串getProperty1();
公共抽象字符串getProperty2();
公共阵列列表getPropertyies(){
ArrayList propertyList=新的ArrayList();
add(getProperty1());
add(getProperty2());
返回属性列表;
}
}
公共类ExampleExtension扩展示例{
公共字符串getProperty1(){return“this is the property”};
公共字符串getProperty2(){return“这是第二个属性”};
}

您应该在抽象类中将字段的范围限制为
private
,并声明用于填充值的构造函数:

public abstract class Example {
    private final String property1;
    private final String property2;

    protected Example(String property1, String property2) {
        this.property1 = property1;
        this.property2 = property2;
    }
    //...
}
然后子类将通过调用
super
构造函数初始化其构造函数中的字段值:

public class ExampleExtension extends Example {

    public ExampleExtension() {
        property1 = "this is the property";
        property2 = "this is the second property";
    }

}
public class ExampleExtension extends Example {

    public ExampleExtension() {
        super("value1", "value2");
        // initialize private fields of ExampleExtension, if any
    }
    // ...
}
在这种情况下,使用不同的抽象方法(如property1、property2)。搜索模板模式的相关阅读

public abstract class Example {
       public ArrayList<String> getPropertyies() {
        ArrayList<String> propertyList = new ArrayList<>();
        propertyList.add(getProperty1());
        propertyList.add(getProperty2());
        return property1;
    }

    public abstract getProperty1();//overriden by other class that has diff value for property1
    public abstract getProperty2();//overriden by other class that has diff value for property2
}
公共抽象类示例{
公共阵列列表getPropertyies(){
ArrayList propertyList=新的ArrayList();
add(getProperty1());
add(getProperty2());
归还财产1;
}
公共抽象getProperty1();//由其他属性1具有diff值的类重写
公共抽象getProperty2();//由其他具有property2差异值的类重写
}

什么是Java
“抽象字段”
?这是一种非常糟糕的编码模式。任何好的IDE都会告诉您,
ExampleExtension.property1
正在隐藏
Example.property1
。如果你讨厌读你的代码的人,包括你自己,就继续写下去。同样的评论也可以说得很好。请以一定的尊重和完整性进行评论。为什么我们要初始化
示例
super(“value1”、“value2”);
)的属性1和属性2?
ExampleExtension
是否有这些字段以及它们的值是什么?
ExampleExtension
之所以有这些字段,是因为它扩展了
示例
。但由于
private
的可见性,它没有直接的读/写访问权限。如果您需要从扩展类读取字段的值,可以在超级类中为它们添加一个getter。谢谢!是的,这些私有字段必须在构造函数中初始化。因为它们没有在
ExampleExtension
中再次定义,它们存在于
Example
中,可以通过getter访问。当我们编写
抽象字符串时,它将显示错误:“这里不允许使用修饰符'abstract'。