Java 方法需要封闭 class 而不是内部 class 的实例
Java method that requires instance of enclosing class but not inner class
如果我有一个非静态内部 class,我知道它不能包含静态方法,因为它需要一个封闭 class 的实例才能访问。但是,有没有办法创建一个可以用外部 class 的实例引用但不能用内部实例引用的方法?大致如下:
public class Family {
public final Set<Dog> pets = new HashSet<Dog>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
Family.this.pets.add(this);
}
public void addDefaultBlack() {
new Dog(Color.BLACK, 10, 10);
}
public void addDefaultWhite() {
new Dog(Color.WHITE, 5, 5);
}
}
}
我可以这样引用它:
Family family = new Family();
family.Dog.addDefaultBlack();
...通过要求外部 class 的实例,而不是内部实例。在这种情况下,Dog
不是静态内部 class 因为每只狗都必须属于一个家庭,但我想要一些方法可以创建具有某些默认属性的狗并将其添加到 Family
封闭 class 的对象。目前我能想到的唯一方法是创建一个枚举(例如 DefaultDogs
之类的东西)并将其作为参数传递到新的构造函数中,然后切换大小写以应用属性。这似乎有些混乱,所以我宁愿避免它。有没有办法用我展示的方法来做到这一点?正确的语法是什么?对不起,如果我在这里遗漏了一些明显的东西。
编辑:我知道我可以在外部 class 中放置一个方法,但在我看来,为了可读性和逻辑,将它保留在内部 class 中对我来说更有意义.这是完成这项工作的唯一方法吗?
addDefaultBlack
方法必须是 outer class 的实例方法,你会调用 family.addDefaultBlackDog()
。可能不是您想要的。
下面就如你所愿。但是您需要将 Family
class 的实例传递给用于创建 Dog
class 的新实例的方法。 addDefault
classes 可以声明为静态的,因此可以通过 vi Family.Dog
.
间接访问它们
import java.awt.Color;
import java.util.HashSet;
import java.util.Set;
public class FamilyDemo {
public static void main(String[] args) {
Family family1 = new Family();
Family family2 = new Family();
family1.new Dog(Color.orange, 70,40);
family2.new Dog(Color.green, 100,200);
Family.Dog.addDefaultBlack(family1);
Family.Dog.addDefaultWhite(family2);
System.out.println(family1.pets);
System.out.println(family2.pets);
}
}
class Family {
public final Set<Dog> pets = new HashSet<>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
pets.add(this);
}
public static void addDefaultBlack(Family instance) {
instance.new Dog(Color.BLACK, 10, 10);
}
public static void addDefaultWhite(Family instance) {
instance.new Dog(Color.WHITE, 5, 5);
}
public String toString() {
return color + ", " + weight + ", " + height;
}
}
}
我考虑了更多,有一些想法供您考虑。
- 除非您打算画宠物,否则不要使用
Color
。它不适合用于描述目的。为 Color 创建一个枚举,并要求将其用作构造函数中的参数。您可以随时添加更多颜色而不影响现有的实现。
- 将
Dog class
更改为 Pet class
。然后你可以有一个可能的宠物枚举。您甚至可以让枚举类型为宠物提供范围,以在值中强制执行不变量。例如,如果您允许 tarantula
作为宠物,您就不会希望它达到 100 磅。 (哎呀!)。只需调整枚举即可添加更多宠物。最小值和最大值以及其他值都可以指定为枚举类型的参数。
- 最后,不仅家庭可以养宠物,单身人士甚至组织也可以。您最初问题的根源是让内部 class 将 dog 的实例添加到封闭的 class 的 Dog 集中。为什么不在 Family 之外拥有一个对其他人有用的 Pet class。您可以将其设为
PetFactory
并带有自定义设置和标准默认宠物。然后留给使用 class 将宠物添加到集合中。
如果我有一个非静态内部 class,我知道它不能包含静态方法,因为它需要一个封闭 class 的实例才能访问。但是,有没有办法创建一个可以用外部 class 的实例引用但不能用内部实例引用的方法?大致如下:
public class Family {
public final Set<Dog> pets = new HashSet<Dog>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
Family.this.pets.add(this);
}
public void addDefaultBlack() {
new Dog(Color.BLACK, 10, 10);
}
public void addDefaultWhite() {
new Dog(Color.WHITE, 5, 5);
}
}
}
我可以这样引用它:
Family family = new Family();
family.Dog.addDefaultBlack();
...通过要求外部 class 的实例,而不是内部实例。在这种情况下,Dog
不是静态内部 class 因为每只狗都必须属于一个家庭,但我想要一些方法可以创建具有某些默认属性的狗并将其添加到 Family
封闭 class 的对象。目前我能想到的唯一方法是创建一个枚举(例如 DefaultDogs
之类的东西)并将其作为参数传递到新的构造函数中,然后切换大小写以应用属性。这似乎有些混乱,所以我宁愿避免它。有没有办法用我展示的方法来做到这一点?正确的语法是什么?对不起,如果我在这里遗漏了一些明显的东西。
编辑:我知道我可以在外部 class 中放置一个方法,但在我看来,为了可读性和逻辑,将它保留在内部 class 中对我来说更有意义.这是完成这项工作的唯一方法吗?
addDefaultBlack
方法必须是 outer class 的实例方法,你会调用 family.addDefaultBlackDog()
。可能不是您想要的。
下面就如你所愿。但是您需要将 Family
class 的实例传递给用于创建 Dog
class 的新实例的方法。 addDefault
classes 可以声明为静态的,因此可以通过 vi Family.Dog
.
import java.awt.Color;
import java.util.HashSet;
import java.util.Set;
public class FamilyDemo {
public static void main(String[] args) {
Family family1 = new Family();
Family family2 = new Family();
family1.new Dog(Color.orange, 70,40);
family2.new Dog(Color.green, 100,200);
Family.Dog.addDefaultBlack(family1);
Family.Dog.addDefaultWhite(family2);
System.out.println(family1.pets);
System.out.println(family2.pets);
}
}
class Family {
public final Set<Dog> pets = new HashSet<>();
public class Dog {
public Color color;
public int weight;
public int height;
public Dog(Color color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
pets.add(this);
}
public static void addDefaultBlack(Family instance) {
instance.new Dog(Color.BLACK, 10, 10);
}
public static void addDefaultWhite(Family instance) {
instance.new Dog(Color.WHITE, 5, 5);
}
public String toString() {
return color + ", " + weight + ", " + height;
}
}
}
我考虑了更多,有一些想法供您考虑。
- 除非您打算画宠物,否则不要使用
Color
。它不适合用于描述目的。为 Color 创建一个枚举,并要求将其用作构造函数中的参数。您可以随时添加更多颜色而不影响现有的实现。 - 将
Dog class
更改为Pet class
。然后你可以有一个可能的宠物枚举。您甚至可以让枚举类型为宠物提供范围,以在值中强制执行不变量。例如,如果您允许tarantula
作为宠物,您就不会希望它达到 100 磅。 (哎呀!)。只需调整枚举即可添加更多宠物。最小值和最大值以及其他值都可以指定为枚举类型的参数。 - 最后,不仅家庭可以养宠物,单身人士甚至组织也可以。您最初问题的根源是让内部 class 将 dog 的实例添加到封闭的 class 的 Dog 集中。为什么不在 Family 之外拥有一个对其他人有用的 Pet class。您可以将其设为
PetFactory
并带有自定义设置和标准默认宠物。然后留给使用 class 将宠物添加到集合中。