Чем объясняется значительное различие в способах привязки методов в Java и C #? - PullRequest
0 голосов
/ 16 января 2011

В Java вызов метода объекта зависит исключительно от типа объекта, а не от ссылочного типа.

В C # ссылочный тип играет важную роль в определении, вызывается ли метод из родительского класса или метод из дочернего класса, в зависимости от того, является ли метод виртуальным или нет.

  1. Является ли приведенное выше утверждение точным?
  2. Почему Java ограничивает это, и не отнимает ли у программиста некоторую власть?

Ответы [ 2 ]

2 голосов
/ 16 января 2011

Ваше определение неверно. В C # это не основано только на том, является ли метод виртуальным. Даже виртуальные методы могут вести себя по-разному в зависимости от типа ссылки. Посмотрите пример ниже и посмотрите на ключевое слово new .

Язык Java прост. Он пытается оставаться простым. Да, это отнимает «некоторую власть», как вы написали, но в качестве компенсации вы получаете чистый код, который легко понять.

Язык C # имеет больше возможностей, но иногда вам нужно изо всех сил пытаться понять все из них. Этот конкретный пример наследования методов с одинаковыми именами является хорошим примером. Мы можем создавать более интересные вещи в C # .... которые никто не поймет.

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

class A {
  public virtual void M1() {
    Console.WriteLine("A.M1()");
  }
}

class B : A {
  public new virtual void M1() {
    Console.WriteLine("B.M1()");
  }
}

class Program {
  static void Main(string[] args) {
    B b = new B();
    b.M1();
    A a = b;
    a.M1();
  }
}

В C # вы получаете два разных результата, хотя у вас один и тот же объект.

0 голосов
/ 16 января 2011

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

например, вы можете написать

Integer i = null;
int j = i.parseInt("1");

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

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

...