嵌套子类实例化声明Java

时间:2018-02-04 00:16:51

标签: java inheritance subclass aggregation

来自JavaScript背景,我发现以下代码有点过于健壮,包含多个语句;我想知道如何简单地编写代码,并在一个语句中完成所有操作。

enter image description here

Student是超类,Friend和Schedule是聚合到超类ArrayList公共成员中的子类(这些不是嵌套类)。这是我目前的代码:

public static void main(String[] args) {

  // Subclass1 instantiation and declaration
  Friend friend_of_andy_1 = new Friend(1002, "Bob");
  ArrayList<Friend> andys_friends = new ArrayList<>();
  andys_friends.add(friend_of_andy_1);    // superclass member

  // Subclass1 instantiation and declaration
  Schedule schedule_of_andy_1 = new Schedule(1, "Yoga practice");
  ArrayList<Schedule> andys_schedule = new ArrayList<>();
  andys_schedule.add(schedule_of_andy_1); // superclass member

  // Superclass instantiation declaration with subclass objects in constructor argument
  Student student_andy = new Student(1001, "Andy", andys_friends, andys_schedule);

}

我想知道我是否可以这样做,我在单个语句中声明/实例化超类和子类;这有可能吗?

public static void main(String[] args) {

  Student student_andy = new Student(
    1001,
    "Andy",
    // instantiation of subclass
    ArrayList<Friend>[
      Friend(
        {
          1002,
          "Bob"
        }
      )
    ],
    ArrayList<Schedule>[
      Schedule(
        {
          1,
          "Yoga practice"
        }
      )
    ]
  )

};

2 个答案:

答案 0 :(得分:2)

首先,您只在一个地方使用friend_of_andy_1,因此您可以将其消除:

List<Friend> andys_friends = new ArrayList<>();
andys_friends.add(new Friend(1002, "Bob"));

其次,如果您对具有固定尺寸的列表感到满意,即您无法向其中添加更多元素,则可以使用Arrays.asList(),而不是创建ArrayList

List<Friend> andys_friends = Arrays.asList(new Friend(1002, "Bob"));

然后,您可以对Schedule执行相同操作,并在创建Student时内联:

Student student_andy = new Student(1001, "Andy",
                                   Arrays.asList(new Friend(1002, "Bob")),
                                   Arrays.asList(new Schedule(1, "Yoga practice")));

如果列表必须可调整大小,则使用ArrayList​(Collection<? extends E> c)构造函数:

Student student_andy = new Student(
        1001,
        "Andy",
        new ArrayList<>(Arrays.asList(
                new Friend(1002, "Bob")
        )),
        new ArrayList<>(Arrays.asList(
                new Schedule(1, "Yoga practice")
        ))
);

当然,无论您想要什么格式化,如果您更喜欢占用太多代码行的分解样式:

Student student_andy = new Student(
    1001,
    "Andy",
    new ArrayList<>(
        Arrays.asList(
            new Friend(
                1002,
                "Bob"
            )
        )
    ),
    new ArrayList<>(
        Arrays.asList(
            new Schedule(
                1,
                "Yoga practice"
            )
        )
    )
);

答案 1 :(得分:1)

好的,基本上,你错过了JSON [脚注-1] 太多了?可以理解的。

下面是一个在Java中创建实例的松散方法集合,以便它尽可能地看起来像JSON。

1)数组:使用内联数组文字

它们在Java中略显冗长,但几乎与JSON中的[ ... ]一样好,例如:

new int[]{1, 2, 3}

是整数数组的文字。

2)对象:定义正确的构造函数

如果您的Friend有构造函数public Friend(int id, String name),那么初始化Friend非常容易和愉快:

new Friend(1234, "Bob")

3)更多对象,更快使用工厂方法

如果您定义工厂方法,则可以删除new。例如。如果你有

class Friend {
    ...
    static Friend friend(int id, String name) { return new Friend(id, name); }
}

然后你甚至可以摆脱new。这在你定义某种嵌入式DSL的很少情况下非常有用,并且真的需要这个构造函数数千次。

4)列表:使用asList

您可以使用Java中的静态导入导入静态方法:

import static java.util.Arrays.asList;

现在您可以使用方便的asList,以便

asList(friend(2, "John"), friend(3, "Bob"))

为您提供朋友列表。

5)地图:使用带有初始化程序块的匿名子类。

这个看起来很疯狂的东西适用于java:

HashMap<String, Integer> hm = new HashMap<>{{
  put("foo", 10);
  put("bar", 20);
}};

这是因为内部花括号包围了一个初始化块,您可以在this上调用方法。

好的,现在您可以轻松创建:

  • 原始资料:字符串,int s,double s
  • 用户定义的对象(使用构造函数和工厂方法)
  • 阵列
  • 解释
  • 地图

这应该足以在Java中创建ad-hoc json-esque数据结构。

现在,假设所有构造函数都已到位,您的代码将变为:

import static java.util.Arrays.asList;

...

Student student_andy = new Student(
  1001,
  "Andy",
  asList(new Friend(1002, "Bob")),
  asList(new Schedule(1, "Yoga practice"))
)

我们在这里没有使用地图,因此初始化程序块的提示只是一个奖励。

[脚注-1] 更确切地说:好像你错过了JavaScript片段,它允许轻松初始化那些规范映射到JSON对象的对象。 JSON当然不是JavaScript。感谢@Andreas指出这一点。