2016-06-03 8 views
2

Пожалуйста, извините мой вопрос, поскольку я попытался найти разницу между использованием супер ключевого слова vs class name, чтобы вызвать метод из суперкласса, но мне не удается найти ответ. Мой вопрос я пытаюсь узнать Java в качестве учебного курса и я использую пример из ссылки: http://www.javatpoint.com/super-keyword используя Пример # 3 и здесь есть код, который я написал:Разница между супер ключевым словом vs имя класса для вызова метода из суперкласса

Я создал супер класс под названием Транспортное средство

public class Vehicle { 
    Vehicle() { 
     System.out.println("Vehicle constructor created"); 
    } 

    public void speed() { 
     int a = 20; 
     System.out.println(a); 
    } 

} 

, а затем создал класс суб имени велосипед со следующим кодом:

public class Bike extends Vehicle { 
    int speed; 

    Bike(int speed1) { 
     this.speed = speed1; 
     System.out.println(speed1); 
     super.speed(); 

    } 

    public static void main(String args[]) { 
     Bike b = new Bike(10); 

    } 

} 

в классе к югу под велосипед конструктора Я использую super.speed() для вызова метода скорости от супер (Vehicle) класс. Теперь, если я изменю эту строку на Vehicle.speed(), я получаю сообщение о том, что мне нужно сделать мой метод скорости статичным.

Я не хочу, чтобы мой метод был статическим и хотел знать о различии между ними.

Приветствия,

+0

Я думаю, причина в том, что если вы используете имя класса.method, это метод доступа статическим способом. Но я не уверен на 100%. Так что просто комментарий :) –

+0

Если вы измените его на this.speed(), он должен работать IMHO :) – Supahupe

ответ

1

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

Что касается вашего вопроса, когда вы создаете объект дочернего класса (класс Bike в этом примере), всегда создается объект его родителя, на основе которого создается конкретный дочерний объект.

Его, как только вы создаете Bike, всегда создается резервная копия Vehicle, на основе которой создается Bike. В противном случае Bike не будет Vehicle.

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

когда вы вызываете метод по имени класса, вы сообщаете компилятор назвать этот метод Vehicle класса, который не связан с каким-либо Vehicle объекта/например, (и, очевидно, не имеет отношения к любому ребенку (например, Bike объекта или экземпляр, а)

2

Методы, которые не являются статическими могут быть вызваны только на конкретном экземпляре объекта. Вот почему вызов Vehicle.speed() будет работать только в том случае, если метод speed был статическим. Причина, по которой вы можете позвонить super.speed(), состоит в том, что в конструкторе вы уже создали объект транспортного средства и в основном вызываете метод на объект, который вы строите.

Для приведенного выше примера я бы сказал, что вызов super.speed() - лучший подход.

Кроме того, поскольку вы не преодолели супер-реализацию метода speed, вы можете так же легко позвонить this.speed() или speed(). Этот подход означал бы, что если вы когда-нибудь решили, что Bike нуждается в различной функциональности в методе speed, ваша конкретная реализация будет вызвана, а не по умолчанию.

1

Эти две конструкции не эквивалентны.

При вызове Vehicle.speed() компилятор ищет метод статического имени speed() в классе с именем Vehicle. Статический метод не принадлежит ни одному экземпляру класса. Вы не можете использовать переменную экземпляра внутри статического метода. Вы не определили статический метод с именем speed() в своем классе Vehicle, и поэтому нет такой вещи, как Vehicle.speed(). Следовательно, вы получаете ошибку компиляции.

При вызове super.speed(), вы не смотрите на статического способом, как и в предыдущем случае: Фактический метод, который будет вызываться при использовании синтаксиса super является экземпляр метод (названный speed() в вашем case), определенный в суперклассе текущего объекта. То есть super.speed() - это метод экземпляра, определенный в суперклассе текущего объекта (в отличие от this.speed(), который является методом экземпляра с именем speed(), определенным в фактическом классе текущего объекта).Другими словами, он будет вызывать метод speed(), определенный в классе Vehicle, но параметр this будет тем, на который ссылается b, текущий объект.

0

Если вы хотите использовать метод непосредственно с именем класса, то вы должны указать метод как статический

public static void speed() { 
    int a = 20; 
    System.out.println(a); 
} 

или

вы можете создать объект класса Vehicle и метод скорости доступа в ваших subsclass как это

Bike(int speed1) { 
    this.speed = speed1; 
    System.out.println(speed1); 
    Vehicle vehicle = new Vehicle(); 
    vehicle.speed(); 
} 
0

привет супер это ключевое слово, которое используется для доступа к методам супер класса в суб классе. Это супер ключевое слово используется в основном, когда методы переопределены.

пример

class A  
{  
    method m()   
} 

class B extends A  
{  
    method m()   

    method m1() 
    {   
     super.m()   
    }   
} 

class C 
{ 
    public static void main(String args[]) 
    { 
     B b = new B(); 

     b.m() // calls method m() in class B 
     b.m1() // calls method m() in class A because method m is pointing to super class method 
    } 
} 
1

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

super является экземпляром родительского класса. Проще говоря имя класса не является экземпляром (это статический контекст для всего класса).

[супер это экземпляр родительского класса?]

said Джон Скит нет такого понятия, как «родительский экземпляр», но я сомневаюсь, что термин экземпляра.

Первоначальная переменная super сначала инициализируется, а затем повороты ребенка, чтобы решить, имеет ли общий доступ к той же переменной/методу (то есть return this.i; в этом виде метода вернет super.i, а не this.i, когда вызов будет выполняться дочерним) или переопределить Это.

import java.util.Random; 
class Love { 

    int i = 1; 
    int hole() { 
     return this.i; 
    } 
} 

class Main extends Love { 

    void wrapper() { 
     System.out.println(super.i); //1 
     System.out.println(this.i); //2 
     super.i = new Random().nextInt(50) + 2; //to avoid compiler pre-optimizing hard coded return value in hole(), so we set again. 
     System.out.println(super.i); //23 
     i = 3; //2nd attempt override 
     this.i = 3; //3rd attempt override 
     System.out.println(hole()); //23, super "instance" keep its own version of this.i 
    } 

    int i = 2; //1st attempt oveeride 
    public static void main(String[] args) { 
     new Main().wrapper(); 
    } 

} 

Так что очевидно, когда ребенок переопределение, супер-прежнему держать свою собственную версию, так что ИМХО супер можно грубо рассматривать как родительский пример, как раз разница с нормальной инстанцией это ключевое слово с некоторым ограничением использования (например, супер .super.i не разрешено, прямой печать супер не допускается). Еще одно отличие заключается в том, что значение переменной будет синхронизироваться в каждом случае из-за того, что ребенок может делиться им, как указано выше.

Вы можете попробовать напечатать super.variable_name внутри статического метода, он будет выводить супер не является статической переменной:

$ javac Bike.java 
Bike.java:132: error: non-static variable super cannot be referenced from a static context 
     System.out.println(super.dummy); 
         ^
Bike.java:132: error: cannot find symbol 
     System.out.println(super.dummy); 
           ^
    symbol: variable dummy 
2 errors 
$ 

Так это сделать смысловую супер как нестатической переменной может доступ не статический способ скорость() в вашем примере.

 Смежные вопросы

  • Нет связанных вопросов^_^