Страницы

Поиск по вопросам

Показаны сообщения с ярлыком override. Показать все сообщения
Показаны сообщения с ярлыком override. Показать все сообщения

среда, 4 марта 2020 г.

UpCast C#.Override и Virtual

#c_sharp #ооп #virtual #override


При создании класса  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Back
{
    class Bugay
    {
        public virtual void Method()
        {
            string b = "Base: ";
            Console.WriteLine(b  + "Здраствуйте,сударь");
        }
        public void Print()
        {
            Console.WriteLine("Class Bugay");
        }

    }
    class Bugay2 : Bugay
    {
        public override void Method()
        {
            string b = "NotBase: ";
            Console.WriteLine(b + "До свидания,сударь");
        }
        new public void Print()
        {
            //base.Print();
            Console.WriteLine("Class Bugay2");
        }

    }
    class OverVirt
    {
        static void Main(string[] args)
        {
            Bugay2 bugay = new Bugay2();
            bugay.Method();
            bugay.Print();
            Console.WriteLine(new string('-',20));
            Bugay nebugay = bugay;
            nebugay.Method();
            nebugay.Print();
            Console.WriteLine(new string('-', 20));
            Bugay nebugay2 = new Bugay();
            nebugay2.Method();
            nebugay2.Print();
            Console.WriteLine(new string('-',20));
            Bugay2 bugay2 = (Bugay2)nebugay;
            bugay2.Method();
            bugay.Print();
            Console.WriteLine(new string('-', 20));
            Console.ReadKey();
        }
    }
}


при UpCast  , метод который был пере-реализован с помощью override и virtual , вызывается
из класса который наследует базовый класс (Bugay2) , то есть который был пере-реализован
в этом классе Вывод:

NotBase: До свидания,сударь
Class Bugay2
--------------------
NotBase: До свидания,сударь
Class Bugay
--------------------
Base: Здраствуйте,сударь
Class Bugay
--------------------
NotBase: До свидания,сударь
Class Bugay2
--------------------


Почему вызывается метод не из базового класса? 
    


Ответы

Ответ 1



Смотрите. Разница между override-цепочкой и new-цепочкой методов состоит в следующем. При указании virtual/override вызывается метод у вашего реального типа, того, которым на самом деле обладает объект. То, какой при этом тип ссылки, по которой вы совершаете вызов, не важно, лишь бы тип этой ссылки содержал метод из вашей override-цепочки. Поэтому для метода Method() важно то, объект какого класса вы создаёте в реальности, а тип ссылки не важен. При указании new вызывается метод у вашего заказанного типа, то есть, типа ссылки, а не реального типа вашего объекта. Поэтому для метода Print() важно, какой тип вашей ссылки, а тип самого объекта не важен.

пятница, 29 ноября 2019 г.

Почему в переопределяемом (@Override) методе нельзя пробросить Exception?

#java #исключения #override


Всем добрый вечер.

Столкнулся с интересной особенностью переопределяемых методов — исключения в них
нельзя пробросить, только обработка внутри метода. Но почему? Хочется получить исчерпывающий
ответ на этот вопрос.
    


Ответы

Ответ 1



Есть два вида исключений в Java — checked и unchecked, подробнее можно почитать, например, в этой статье. Checked исключения проверяются на этапе компиляции приложения, и должны где-то отлавливаться (catch), а методы, которые выбрасывают такие исключения, должны иметь в сигнатуре тип исключения, который может быть выброшен (напр. void method() throws Exception). При переопределении (@Override) метода, в сигнатуре которого не указан throws, нельзя бросить checked-исключение, потому что компилятор не сможет его отследить. Нерабочий пример: class A { void foo() {} } class B extends A { @Override void foo() throws Exception {} } A obj = new B(); obj.foo(); // Компилятор рассматривает obj как A, в котором нет throws, и не знает о том, что он бросает checked-исключение Вы можете бросить unchecked-исключение, на основе RuntimeException или Error, без добавления throws в сигнатуру перезагруженного метода. Конечно, если вам не нужно именно checked-исключение.

Ответ 2



Можно, если переопределяемый метод суперкласса объявлен, как выбрасывающий тот же тип исключений или базовый к нему. Это один из основных принципов ООП - LSP.

вторник, 21 мая 2019 г.

UpCast C#.Override и Virtual

При создании класса
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace Back { class Bugay { public virtual void Method() { string b = "Base: "; Console.WriteLine(b + "Здраствуйте,сударь"); } public void Print() { Console.WriteLine("Class Bugay"); }
} class Bugay2 : Bugay { public override void Method() { string b = "NotBase: "; Console.WriteLine(b + "До свидания,сударь"); } new public void Print() { //base.Print(); Console.WriteLine("Class Bugay2"); }
} class OverVirt { static void Main(string[] args) { Bugay2 bugay = new Bugay2(); bugay.Method(); bugay.Print(); Console.WriteLine(new string('-',20)); Bugay nebugay = bugay; nebugay.Method(); nebugay.Print(); Console.WriteLine(new string('-', 20)); Bugay nebugay2 = new Bugay(); nebugay2.Method(); nebugay2.Print(); Console.WriteLine(new string('-',20)); Bugay2 bugay2 = (Bugay2)nebugay; bugay2.Method(); bugay.Print(); Console.WriteLine(new string('-', 20)); Console.ReadKey(); } } }
при UpCast , метод который был пере-реализован с помощью override и virtual , вызывается из класса который наследует базовый класс (Bugay2) , то есть который был пере-реализован в этом классе Вывод:
NotBase: До свидания,сударь Class Bugay2 -------------------- NotBase: До свидания,сударь Class Bugay -------------------- Base: Здраствуйте,сударь Class Bugay -------------------- NotBase: До свидания,сударь Class Bugay2 --------------------
Почему вызывается метод не из базового класса?


Ответ

Смотрите.
Разница между override-цепочкой и new-цепочкой методов состоит в следующем.
При указании virtual/override вызывается метод у вашего реального типа, того, которым на самом деле обладает объект. То, какой при этом тип ссылки, по которой вы совершаете вызов, не важно, лишь бы тип этой ссылки содержал метод из вашей override-цепочки.
Поэтому для метода Method() важно то, объект какого класса вы создаёте в реальности, а тип ссылки не важен.
При указании new вызывается метод у вашего заказанного типа, то есть, типа ссылки, а не реального типа вашего объекта.
Поэтому для метода Print() важно, какой тип вашей ссылки, а тип самого объекта не важен.

среда, 3 октября 2018 г.

Почему в переопределяемом (@Override) методе нельзя пробросить Exception?

Всем добрый вечер.
Столкнулся с интересной особенностью переопределяемых методов — исключения в них нельзя пробросить, только обработка внутри метода. Но почему? Хочется получить исчерпывающий ответ на этот вопрос.


Ответ

Есть два вида исключений в Java — checked и unchecked, подробнее можно почитать, например, в этой статье
Checked исключения проверяются на этапе компиляции приложения, и должны где-то отлавливаться (catch), а методы, которые выбрасывают такие исключения, должны иметь в сигнатуре тип исключения, который может быть выброшен (напр. void method() throws Exception). При переопределении (@Override) метода, в сигнатуре которого не указан throws, нельзя бросить checked-исключение, потому что компилятор не сможет его отследить. Нерабочий пример:
class A { void foo() {} }
class B extends A { @Override void foo() throws Exception {} }
A obj = new B(); obj.foo(); // Компилятор рассматривает obj как A, в котором нет throws, и не знает о том, что он бросает checked-исключение
Вы можете бросить unchecked-исключение, на основе RuntimeException или Error, без добавления throws в сигнатуру перезагруженного метода. Конечно, если вам не нужно именно checked-исключение.