说,我有一个包含A
和B
类的包A
。 Pack
是自包含的,任何人(即使在A
中)都应该看到private
的内部,因此大多数字段和方法都是A
。
现在我想扩展private
以更改其中一个AMod
方法,保留其余内容 - 让它成为类A
。这样做需要大多数protected
个字段,并且要覆盖的方法为protected
,但AMod
可以访问该包。
那么如何在Pack
内创建AMod
,以便A
可以访问$window.location.href
的字段和方法而其他人没有?制作一个嵌套/单独的包?
UPD:
UPD2:
UPD3:
正如Jacob G.建议的那样,我的代码需要重新设计,我设法从架构中删除派生类。谢谢你的帮助!
答案 0 :(得分:1)
我发现缺少的一个答案:不要那么专注于使用继承以避免代码重复。
如果您只需要A
行为的微妙变化,那么您应该首先考虑“围绕”A
(例如通过decorator)而不是extending
A - 好老FCoI!
如果无法做到这一点:请仔细查看A
和Amod
的常见行为,并在 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 fields
和2)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() {...}
}