Лучший способ обработать несколько конструкторов в Java

Проблема заключается в том условии, которое вы используете здесь:

for (int i=0; i<1-n; i++)

, если n равно 6, (1 - n) будет -5. Начальное значение i = 0. Поскольку 0 < -5 - ложь, она выбивает тебя из колеи.

Вместо этого используйте n - 1

for (int j=i+1; j<1-i-n; j++)

Аналогично, здесь используйте n - i - 1.

Помимо этого, проверьте из хорошего ресурса, правильно ли вы его реализуете.

См. Это: https://www.geeksforgeeks.org/bubble-sort/

.

74
задан typeoneerror 2 January 2011 в 08:02
поделиться

8 ответов

Немного упрощенный ответ:

public class Book
{
    private final String title;

    public Book(String title)
    {
      this.title = title;
    }

    public Book()
    {
      this("Default Title");
    }

    ...
}
141
ответ дан Craig P. Motlin 24 November 2019 в 11:49
поделиться

Рассмотрите использование шаблона Разработчика. Это позволяет, чтобы Вы установили значения по умолчанию на своих параметрах и инициализировали ясным и кратким способом. Например:


    Book b = new Book.Builder("Catcher in the Rye").Isbn("12345")
       .Weight("5 pounds").build();

Редактирование: Это также устраняет необходимость нескольких конструкторов с различными подписями и является более читаемым путем.

36
ответ дан kgrad 24 November 2019 в 11:49
поделиться

Необходимо определить то, что является инвариантами класса, т.е. свойствами, которые всегда будут верны для экземпляра класса (например, заголовок книги никогда не будет пустым, или размер собаки всегда будет> 0).

Эти инварианты должны быть установлены во время конструкции и сохранены вдоль времени жизни объекта, что означает, что методы не должны повреждать инварианты. Конструкторы могут установить эти инварианты или при наличии обязательных аргументов, или путем установки значений по умолчанию:

class Book {
    private String title; // not nullable
    private String isbn;  // nullable

    // Here we provide a default value, but we could also skip the 
    // parameterless constructor entirely, to force users of the class to
    // provide a title
    public Book()
    {
        this("Untitled"); 
    }

    public Book(String title) throws IllegalArgumentException
    {
        if (title == null) 
            throw new IllegalArgumentException("Book title can't be null");
        this.title = title;
        // leave isbn without value
    }
    // Constructor with title and isbn
}

Однако выбор этих инвариантов высоко зависит от класса, который Вы пишете, как Вы будете использовать его, и т.д., таким образом, не будет никакого категорического ответа на Ваш вопрос.

19
ответ дан Luc Touraille 24 November 2019 в 11:49
поделиться

Необходимо всегда создавать допустимый и законный объект; и если Вы не можете с помощью детских колясок конструктора, необходимо использовать объект разработчика создать один, только выпуская объект от разработчика, когда объект завершен.

По вопросу об использовании конструктора: Я всегда пытаюсь иметь одного основного конструктора, которому все другие подчиняются, объединяя в цепочку через с "опущенными" параметрами следующему логическому конструктору и заканчиваясь в основном конструкторе. Так:

class SomeClass
{
SomeClass() {
    this("DefaultA");
    }

SomeClass(String a) {
    this(a,"DefaultB");
    }

SomeClass(String a, String b) {
    myA=a;
    myB=b;
    }
...
}

, Если это не возможно, то я пытаюсь иметь частный init () метод, которому подчиняются все конструкторы.

И сохраняют число конструкторов и параметров маленьким - макс. из 5 из каждого как инструкция.

12
ответ дан Lawrence Dol 24 November 2019 в 11:49
поделиться

Некоторые общие подсказки конструктора:

  • Попытка сфокусировать всю инициализацию в единственном конструкторе и назвать ее от других конструкторов
    • Это работает хорошо, если несколько конструкторов существуют для моделирования параметров по умолчанию
  • , Никогда не называют непоследний метод от конструктора
    • , Закрытые методы являются окончательными по определению
    • , Полиморфизм может уничтожить Вас здесь; можно закончить тем, что назвали реализацию подкласса, прежде чем подкласс был инициализирован
    • , Если Вы нуждаетесь в методах "помощника", несомненно, сделаете их частными или окончательными
  • Быть явными в Ваших вызовах к супер ()
    • , Вы были бы удивлены тем, сколько программистов Java не понимает, что супер () назван, даже если Вы явно не пишете это (предположение, что у Вас нет вызова к этому (...))
  • , Знают порядок правил инициализации для конструкторов. Это в основном:

    1. это (...), если существующий ( всего перемещение другому конструктору)
    2. вызов супер (...) [если не явный, звоните супер () неявно]
    3. (создайте суперкласс с помощью этих правил рекурсивно)
    4. инициализируют поля через их объявления
    5. выполненное тело текущего конструктора
    6. возврат предыдущим конструкторам (если Вы встретились, это (...) звонит)

, полный поток заканчивает тем, что был:

  • перемещение полностью супериерархия классов для Возражения
  • , в то время как не сделанный
    • init поля
    • выполненные тела конструктора
    • выпадающий для разделения на подклассы

Для хорошего примера зла попытайтесь выяснить то, что следующее распечатает, затем выполнить его

package com.javadude.sample;

/** THIS IS REALLY EVIL CODE! BEWARE!!! */
class A {
    private int x = 10;
    public A() {
        init();
    }
    protected void init() {
        x = 20;
    }
    public int getX() {
        return x;
    }
}

class B extends A {
    private int y = 42;
    protected void init() {
        y = getX();
    }
    public int getY() {
        return y;
    }
}

public class Test {
    public static void main(String[] args) {
        B b = new B();
        System.out.println("x=" + b.getX());
        System.out.println("y=" + b.getY());
    }
}

, я добавлю комментарии, описывающие, почему вышеупомянутые работы, как это делает... Часть его может быть очевидной; некоторые не...

6
ответ дан Scott Stanchfield 24 November 2019 в 11:49
поделиться

Другое соображение, если поле требуется или имеет ограниченный диапазон, выполняет регистрацию конструктора:

public Book(String title)
{
    if (title==null)
        throw new IllegalArgumentException("title can't be null");
    this.title = title;
}
3
ответ дан Steve Kuo 24 November 2019 в 11:49
поделиться

Я сделал бы следующее:

public class Book
{
    private final String title;
    private final String isbn;

    public Book(final String t, final String i)
    {
        if(t == null)
        {
            throw new IllegalArgumentException("t cannot be null");
        }

        if(i == null)
        {
            throw new IllegalArgumentException("i cannot be null");
        }

        title = t;
        isbn  = i;
    }
}

я делаю предположение здесь что:

1) заголовок никогда не будет изменяться (следовательно, заголовок является окончательным), 2), ISBN никогда не будет изменяться (следовательно, ISBN является окончательным), 3), что это не допустимо, чтобы иметь книгу и без заголовка и без ISBN

, Рассматривают Студенческий класс:

public class Student
{
    private final StudentID id;
    private String firstName;
    private String lastName;

    public Student(final StudentID i,
                   final String    first,
                   final String    last)
    {
        if(i == null)
        {
            throw new IllegalArgumentException("i cannot be null"); 
        }

        if(first == null)
        {
            throw new IllegalArgumentException("first cannot be null"); 
        }

        if(last == null)
        {
            throw new IllegalArgumentException("last cannot be null"); 
        }

        id        = i;
        firstName = first;
        lastName  = last;
    }
}

Там Студент должен быть создан с идентификатором, именем и фамилией. Студенческий идентификатор никогда не может изменяться, но фамилия людей и имя могут измениться (женитесь, меняет имя из-за проигрывания пари, и т.д....).

При решении, что конструкторов иметь Вас действительно должен думать о том, что имеет смысл иметь. Все часто людям добавляют, устанавливал/получал методы, потому что их преподают к - но очень часто это - плохая идея.

Неизменные классы намного лучше иметь (который является классами с последними переменными) по изменяемым. Эта книга: http://books.google.com/books?id=ZZOiqZQIbRMC&pg=PA97&sig=JgnunNhNb8MYDcx60Kq4IyHUC58#PPP1,M1 (Эффективный Java) имеет хорошее обсуждение неизменности. Взгляд на объекты 12 и 13.

0
ответ дан TofuBeer 24 November 2019 в 11:49
поделиться

Несколько человек рекомендовали добавить пустую проверку. Иногда это - правильный поступок, но не всегда. Проверьте эту превосходную статью, показывающую, почему Вы пропустили бы ее.

http://misko.hevery.com/2009/02/09/to-assert-or-not-to-assert/

0
ответ дан Craig P. Motlin 24 November 2019 в 11:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: