如何正确地继承字段而不使它们对包打开?

时间:2017-05-06 15:35:16

标签: java oop

说,我有一个包含AB类的包APack是自包含的,任何人(即使在A中)都应该看到private的内部,因此大多数字段和方法都是A

现在我想扩展private以更改其中一个AMod方法,保留其余内容 - 让它成为类A。这样做需要大多数protected个字段,并且要覆盖的方法为protected,但AMod可以访问该包。

那么如何在Pack内创建AMod,以便A可以访问$window.location.href的字段和方法而其他人没有?制作一个嵌套/单独的包?

UPD:

UPD2:

UPD3:

正如Jacob G.建议的那样,我的代码需要重新设计,我设法从架构中删除派生类。谢谢你的帮助!

3 个答案:

答案 0 :(得分:1)

我发现缺少的一个答案:不要那么专注于使用继承以避免代码重复。

如果您只需要A行为的微妙变化,那么您应该首先考虑“围绕”A(例如通过decorator)而不是extending A - 好老FCoI

如果无法做到这一点:请仔细查看AAmod常见行为,并在 common中提取这些部分基类。

最后:首先,不要让精力充沛地了解java访问修饰符。最后,他们帮助您传达某种想法或想法。 “邪恶的”人们总会找到一种方法来解决你的意图。我的意思是:如果你担心你的团队成员以错误的方式使用你的课程......这是一个社交问题;你将从不能够在技术层解决这个问题。你必须在社交层上解决它(通过教育人来确保他们理解做什么;而不是希望private在这里或{ {1}}会阻止他们做错事。)

换句话说:建立一个简单的政策,例如“只有标记为protected的内容是public;其他任何内容都不是”可能始终能够提出这样的讨论。与花费数小时和数小时在源代码中找到完美的私有保护解决方案。

答案 1 :(得分:0)

感谢您发布代码。

我的建议是先将B#stepBMod移至A.java。然后,您可以将boolean参数传递给A#build;有了这个,你可以重写A#build

public Result build(boolean mod) {
    stepA();

    if (mod) {
        stepBMod();
    } else {
        stepB();
    }

    stepC();

    return result;
}

现在,我不再需要B.java

答案 2 :(得分:-1)

你的问题分为两部分。 1)Accessing fields2)Accessing methods

案例1),您应该创建A个字段protected。这意味着没有人可以通过名称访问它,除了derived classes

案例2),您无法按名称访问protected方法,除非在derived class中。但您仍然可以使用protected对象按名称访问A方法。为了防止其他类创建对象,您的A类应该是抽象的。

这是一个例子

public abstract class A{
    protected int n;
    protected void display(){
        System.out.println(n);
    }
}

public class B extends A{
    public void demo(){
        B object = new B();  
        object.display();   
    }
    public void modify(){
        n = 0;
    }
}

更新

class A
{
public A(Args args){...}
public Result build() {
    stepA();
    stepB();
    stepC();
    return result;
}
protected void stepA() {...}
private void stepB() {...}
protected void stepC() {...}
protected T field;
}

class AMod extends A
{
public AMod(Args args){
super(args);
...
}
public Result build() {
    stepA();
    stepBMod();
    stepC();
    return result;
}
private void stepBMod() {...}
}