类的多个实例与数组Java

时间:2016-09-04 09:44:22

标签: java oop

我的问题以下哪个例子代表了正确的做法? 这些方法有哪些优点和缺点。 是否有另一种(正确的)方法来实现这一目标?

我们说我上课

public class Person {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String print() {
        return this.name;
    }
}

使用类如:

public static void main(String[] args) {
        List<Person> people = new ArrayList<Person>();
        people.add(new Person("Jane Doe"));
        System.out.println(people.get(0).print());
}

然后另一种方法:

public class Persons {

    private ArrayList<String> persons;

    public Persons() {
        persons = new ArrayList<String>();
    }

    public void putPerson(String name) {
         persons.add(name);
    }

    public String print(int id) {
        return this.persons.get(id);
    }
}

使用它:

public static void main(String[] args) {
        Persons persons = new Persons();
        persons.putPerson("John Doe");
        System.out.println(persons.print(0));
    }

编辑:

假设我有10 000名这些人。 创建10,000个类的实例是否有任何缺点?

4 个答案:

答案 0 :(得分:1)

我更喜欢第一种方式,因为很少需要创建一个用于保存集合的包装类(如Persons - &gt; Person)。如果将类Persons重命名为Company / Community,其中包含List个工作人员/人员并在此列表中提供特定操作,则这是有意义的。

public String showAllMembers() { ... }
public void notifyAllMembers() { ... }

此外,第二种方式打破了Single responsibility principle。它不应该照顾打印一个人,该类负责添加/删除它们。 Persons可以为您提供特定的Person,然后您必须在给定的实例上调用方法print()

Persons persons = ...;
persons.getMember(10).print(); 
  

假设我有这些人中的一万人。创建10 000个类的实例是否有任何缺点?

无论如何,您必须创建10000多个实例。考虑,

  • 10000 Person s + a List
  • 10000 Person s + a Persons + a List

答案 1 :(得分:1)

第一个比第二个更面向对象,一旦你开始向一个人添加更多属性,它就会变得明显。

例如,考虑为某人添加出生日期。如果您拥有class Person,则可以修改该课程,并且每个有权访问该课程的人都可以获得该课程。您还将使用Person对象传递出生日期,因此任何以Person为参数的方法都可以访问该人的出生日期:

static void displayPerson(Person p) {
    // Here, we can print both the name and the date of birth / age
}
public static void main(String[] args) {
    ...
    displayPerson(people.get(0));
}

第二种方法需要向Persons类添加并行集合。 Persons的所有用户都可以访问出生日期,但除非方法将完整集合作为参数,否则它只能访问调用者从集合中获取的属性:

void displayPerson(String name) {
    // Here, we have no access to person's date of birth
}
public static void main(String[] args) {
    ...
    displayPerson(persons.print(0));
}

答案 2 :(得分:1)

在Java中,第一种方法是。它更符合OOP的做事方式。

虽然第二个没有结构上的错误,但它并没有遵循OOP架构。您可以在C中执行此类操作。

在第一种方法中,您创建了一个Person类,它定义了一个人 - 它的属性,方法等。这是面向对象编程中的对象。当您需要putPerson时,您可以实例化一个并将其添加到人员列表中。

在第二部分中,您基本上创建了一个数组。然后,您可以创建它的实例并填写所需的属性。但是,我认为这种方法有以下缺点:

  • 您添加到课程中的对象不再存在。你没有定义一个人是什么以及它拥有什么属性。这些属性仅存在于您添加到数组的值中。这可能会在一段时间后变得非常混乱和冒险。

  • 没有吸气剂和二传手。检索特定属性并更新它的每个操作都将导致阵列上非常复杂和冗余的迭代。此外,您的类可能具有大量属性,并且每次要更新属性时,您都必须非常小心地在数组中获取该属性的正确索引。这是灾难的秘诀。

  • 另外,float方法只是为数组添加一个值? Cringy。

简短的回答:不要用Java做第二种方式。

答案 3 :(得分:0)

在我看来,A比B更容易理解,因此我会说代码可读性和可维护性更好。

原因是,例如B persons结构实际上涉及另一个结构ArrayList的组合以完成泛型,在示例A中,您通过声明List<Person>来实现它。

示例B也不如A灵活,因为它始终是一个集合,而示例A您只需将其用作Person并将其插入Java中可用的不同数据结构中。例如,如果你想跟踪独特的人,你可以很容易地得到一个由<name, Person>键入的地图,而例子B则不会那么干净,因为你会做<name, Persons>之类的事情。每个persons只包含1个人。因此,可扩展性可能不如另一个那么大。

同样对我来说,A更像传统的面向对象的方式,因为你将一个真实世界的对象表示为一个类,而B实际上只是一个对象的包装器。

显然可能会有很多争论,但我很满意其他人对这个答案的投入和批评。