Разница между конструкторами и методами

Ниже приведен пример, который я нашел в Tutorials Points, пример конструктора. Я получил большинство из них, но я просто не понимаю, зачем вам нужен конструктор и метод.

public Puppy(String name){
    System.out.println("Passed Name is :" + name ); 
}

Мой вопрос: что мешает вам делать это вместо этого?

public static void Puppy(String name){
    System.out.println("Passed Name is: "+name);
}

Разве эти два не делают одно и то же одно слово?

Вот полная программа для справки:

public class Puppy {
    int puppyAge;

    public Puppy(String name) {
        System.out.println("Passed Name is :" + name); 
    }

    public void setAge(int age) {
        puppyAge = age;
    }

    public int getAge() {
        System.out.println("Puppy age is :" + puppyAge); 
        //what does this return do? since the puppyAge is already printed above.
        return puppyAge;
    }

    public static void main(String []args){
        Puppy myPuppy = new Puppy("tommy");

        myPuppy.setAge(2);
        myPuppy.getAge();

        System.out.println("Variable Value :" + myPuppy.puppyAge); 
    }
}

Ответ 1

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

Я уверен, что вы знаете, что такое машина; вы знаете, что он позволяет вам перемещаться из одного места в другое, чтобы он имел 4 колеса и так далее. Это концепция, и фактический автомобиль, который у вас есть в вашем гараже, представляет собой экземпляр этого понятия (<= > class).

Цель конструктора - создать экземпляр, а не печатать какой-либо текст. Без конструктора вы никогда не сможете вызвать нестатический метод вашего класса. Вы не сможете управлять концепцией автомобиля, вам сначала нужно будет построить автомобиль.

Просто просмотрите эти понятия; вы не получите нигде без него.

Ответ 2

Я думаю, ваш вопрос в том, почему конструктор создается с помощью...

public Puppy(String name)

... вместо...

public static void Puppy(String name)

..., right?

Если это так, во-первых, вы должны теперь, чтобы конструктор был специальным методом, принадлежащим классу, который вызывается всякий раз, когда вы создаете новый экземпляр этого класса. Итак, если, например, у вас есть этот класс...

public class Clazz {
    public Clazz (String s) {
         System.out.println(s);
    }
}

..., тогда всякий раз, когда вы создаете новый экземпляр этого класса, например...

Clazz c = new Clazz("Hello World");

..., будет вызываться конструктор и этот метод будет выполнен. (В этом примере на экране будет напечатан "Hello World".)

Тем не менее, вы можете видеть, что конструктор - это метод, но это специальный метод, вызываемый при создании экземпляра класса. Таким образом, в отношении вашего вопроса причина, почему конструктор прав именно так, а не обычный заголовок метода, указывает компилятору, что это конструктор и не обычный метод. Если вы пишете public void Clazz () вместо public Clazz (), тогда компилятор не узнает ваш конструктор и будет считать его обычным методом.

Обратите внимание, что конструкторы никогда ничего не возвращают, поэтому нет необходимости использовать ключевое слово void. Кроме того, нет смысла создавать конструктор static, поскольку конструктор вызывается при создании экземпляра нового объекта.

Ответ 3

Конструкторы. Методы ARE - это специальные типы методов. Конструкторы - это методы, которые не имеют типа возвращаемого значения и должны быть названы в честь их окружающего класса. Итак, зачем нам нужны конструкторы? хорошо, что мы можем создавать экземпляры классов. Когда вы хотите создать экземпляр определенного класса, вы делаете это, вызывая его конструктор. Конструктор резервирует память для объекта и возвращает ссылку на вновь созданный объект.

Ответ 4

В Java Spec for Constructors:

  • Конструкторы ничего не возвращают, поэтому они не имеют типа возврата.

    Во всех других отношениях объявление конструктора выглядит так же, как объявление метода, которое не имеет результата (§8.4.5).

  • Вы не можете переопределить конструктор.

    Объявления конструктора не являются членами. Они никогда не унаследованы и поэтому не подлежат сокрытию или переопределению.

  • Они не могут напрямую обращаться к переменным экземпляра, вместо этого они должны использовать this и super для делегирования переменных класса.

    Явный оператор вызова конструктора в теле конструктора может не ссылаться на какие-либо переменные экземпляра или методы экземпляра или внутренние классы, объявленные в этом классе или любом суперклассе, или использовать это или супер в любом выражении; в противном случае возникает ошибка времени компиляции.

Ответ 5

Существует большая разница между конструкторами и методами. Когда вы создаете экземпляр объекта, как это сделано в программе

Puppy myPuppy = new Puppy( "tommy" );

с использованием нового ключевого слова JVM вызывает конструктор для создания объекта. Поэтому конструкторы создают объекты, которые не существуют, но методы связаны с объектами, которые существуют. Вы можете прочитать больше по этой ссылке http://www.javaworld.com/article/2076204/core-java/understanding-constructors.html

Ответ 6

несколько хороших ответов о конструкторах уже.

Маленькая точка; вы не можете иметь статический метод с тем же именем, что и ваш класс. Это имя зарезервировано для конструкторов.

Ответ 7

Предполагается, что конструктор должен создать объект, где как метод просто выполняет какое-либо действие с объектом. Java объектно ориентирована, поэтому весь язык вращается вокруг объекта. Конструкторы также не могут возвращать что-либо и должны использоваться с новым, чтобы возвращать экземпляр объекта, созданного там, где методы могут возвращать что-либо или ничего вообще.

Ответ 8

A Constructor делает именно это, он "конструирует" объект, который вы его создаете технически, является определенным типом Method. A Method используется для модификации объекта, в основном для выполнения одной части логики. См. single responsibility principle.

Классы/методы должны быть простыми и обрабатывать точные фрагменты информации, например, принимать объект Shape, если вы хотите, чтобы атрибуты были длиной, шириной, высотой, объемом, областью и т.д.... ваш конструктор должен был бы быть:

public Shape (double length, double width, double height, double volume, double area, ect...) {
    //code here
} 

(обратите внимание, что имя этого метода должно быть таким же, как имя класса, означающее "конструктор" )

это то, что известно как code smell, а именно: слишком много параметров. Трудно читать, не очень организованно и просто плохо писать код. Поэтому вместо этого используются методы для установки этих переменных:

public void setLength(double length) {
    //code here
} 

Тогда ваш конструктор будет только:

public Shape() {
    //code here
}

Это просто один простой пример. Во многих случаях вы можете передать параметр (или несколько) в конструктор в зависимости от случая.

Ответ 9

Для этого примера вам не нужен конструктор. Это довольно плохой пример. Метод будет работать так же хорошо.

(Все классы Java имеют конструктор по умолчанию, если вы его не добавили, поэтому вы можете вызвать new Puppy(), чтобы получить экземпляр.)

Ответ 10

Когда вы создаете новый экземпляр объекта (Puppy doggy = new Puppy("Bobby");), конструктор немедленно вызывается. Он создает новые объекты. Он строит его с именем "Бобби". (Щенок рождается с именем "Бобби" ). Скажем, наш щенок недоволен своим именем, и вы хотите изменить его на "Snoopy". Затем вы вызываете метод: doggy.setName("Snoopy");

Ответ 11

Конструктор - это тип метода. В частности, он вызывается, когда вы создаете экземпляр объекта этого класса. Поэтому в вашем примере, если вы пишете:

Puppy pup = new Puppy("Rover");

Вы создаете объект с именем pup и создаете экземпляр этого объекта, который позволяет вам его использовать. Создав экземпляр, вы вызываете указанный конструктор в этом случае: public Puppy(String name), который устанавливает отпечатки на "Rover", однако это не очень полезно использовать конструктор. Что будет более разумным, так это иметь String puppyName; как переменную поля и this.puppyName = name установить p.puppyName равную тому, что передается в конструкторе.

Ответ 12

Я бы скорее прочитал книгу о концепциях ООП и в этом случае java, чем читал все (хорошие) ответы здесь. Вероятно, вы получите много ответов, так как этот вопрос довольно популярен, но ответы не будут вдаваться в все необходимые детали.

Но я хочу сказать коротко:

public int getAge() {
    System.out.println("Puppy age is :" + puppyAge); 
    //what does this return do? since the puppyAge is already printed above.
    return puppyAge;
}

Метод может вернуться с каким-то ответом. Так что же делает этот метод? Он возвращает значение, сохраненное в переменной с именем puppyAge, который является целым числом. Поэтому, если вы вызываете метод myPuppy.getAge(), все в этом методе (действительно, распечатка тоже) будет обработан, а затем он будет возвращен. В вашем случае вы не сохраняете возвращаемое значение в любом месте. Но "нормальная" вещь, которую вы хотите сделать, - это получить доступ к возрасту щенка с помощью метода и на самом деле что-то с этим делать, например, рассчитать средний возраст всех ваших щенков и прочее. Конечно, вы можете получить доступ к переменной здесь вне класса, потому что вы не установили модификатор видимости, например public, private, protected.

public class Puppy {
    int puppyAge;

На самом деле никакого публичного модификатора также не имеет значения, но пока это не актуально. Итак, что вы хотите сделать, это установить его, например, на частную:

private int age;

и получить доступ к нему с помощью метода типа getAge() и сделать с ним что-то вроде:

int allAgesummed = puppy1.getAge() + puppy2.getAge() +
puppy3.getAge();

Наконец, если вы просто хотите распечатать возраст на консоли, ваш метод должен делать только одну вещь и должен быть назван соответствующим образом, например:

public void printAgeToConsole(){
    System.out.println("Age: " + age);
}

void указывает, что этот метод что-то делает, но ничего не возвращает.

Ответ 13

Конструктор

public Class() { определить переменную, которая должна использоваться в целом классе метод идет под конструктором public void methodName() {} u может изменить void на тип переменной, чтобы u хотел, чтобы метод возвращал определенный тип.

Ответ 14

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

public class Puppy{
    private String puppyName;

    public Puppy(String name){
        puppyName = name;
    }
    public void bark(){
        System.out.println(puppyName + ": woof!");
    }
    ...
}
...
public static void main(){
    Puppy Spot = new Puppy("Spot"); // here, the constructor is called, which saves the name
                                    // "Spot" into the variable Spot.puppyName.

    Puppy Fido = new Puppy("Fido"); // on this line, the constructor is called again, but this time, the string
                                    // "Fido" is saved into Fido.puppyName.

    Spot.bark();                    // output: "Spot: woof!"
}

Я думаю о конструкторе как методе, который "возвращает" объект Puppy, поэтому он не имеет типа возврата. Методы и переменные, объявленные статическими, в отличие от имени щенка, не "принадлежат" к любому объекту в частности, но распределяются между всеми членами класса.

public class Puppy{
    ...
    private static String latinName;
    public static void setLatinName(String newLatinName){
        latinName = newLatinName;
    }
    public static void printLatinName(){
        System.out.println("I am a " + latinName + ".");
    }
};
...
static void main(){
    Puppy Spot("Spot");
    Puppy Fido("Spot");
    Spot.setLatinName("Canis Lupus");
    Fido.setLatinName("Canis Lupus Familiaris");

    Spot.printLatinName();    // output: "I am a Canus Lupus Familiaris."
    // even though we used the Fido object to change the latinName string,
    // the output of Spot non-static method still reflects the change because
    // latinName is a static field: there is only one String latinName 
    // shared among all members of the class.
}

Пока вы можете использовать объект Puppy для вызова статических методов (что может быть особенно полезно, если щенок является полиморфным Canine), обратное тоже не верно!

public class Puppy{
    ...
    public static void bark(){
        System.out.println( puppyName + ": woof!"); // this will not compile!
    }
}

Недействительно (и не имеет смысла) ссылаться на нестатические элементы данных в контексте статической функции! Статическая функция похожа на статическую переменную: существует только одна копия функции, разделяемой между всеми объектами-членами. Это означает, что вы можете вызвать Puppy.setLatinName() (вместо Spot.setLatinName()). Вам не нужно использовать определенный объект Puppy для вызова статической функции: статическая функция гарантируется, что она не будет зависеть от каких-либо нестатических переменных-членов (потому что их нет). Вызов Puppy.bark() не имеет смысла, поскольку класс "Puppy" не имеет имени puppyName; у каждого отдельного щенка есть собственное имя puppyName.

Надеюсь, это поможет. Объектно-ориентированное программирование очень мощное, и важно хорошо понимать основы! Удачи.