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

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

var queryString = $('#myFormId').formSerialize();

От http://malsup.com/jquery/form

Или использование прямого jQuery:

var queryString = $('#myFormId').serialize();

5
задан Alfred Myers 9 June 2012 в 13:43
поделиться

10 ответов

Потому что B делает все, что делает A, но A не обязательно делает все, что делает B. Подумайте об этом так:

AClass --> Shape
BClass --> Circle

Shape a = new Shape();
Circle b = new Circle();

a = b; // works because a is of type "Shape" and a circle is a specific shape
b = a; // doesn't work because b is of type "Circle" and a could be a square.
15
ответ дан 18 December 2019 в 05:24
поделиться

Let's change the name of the classes from AClass to Mammal and BClass to Dog.


a = b; // you're putting a dog on a variable of type Mammal. That's OK.
b = a; // You're putting a mammal (could be a cat, a monkey, etc.) on a variable of type Dog.

Maybe not the best example, but it may be enough for you to understand.

8
ответ дан 18 December 2019 в 05:24
поделиться

This directly follows from the Liskov Substitution Principle:

Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T

In other words, the derived class can always be used in place of the base class. It's usually not possibel the other way round - because the base class can't do what the derived class does.

(I know I am mixing up the timeline here - inheritance was first, Liskov came second - but she put nicely how inheritance is intended to be used)

4
ответ дан 18 December 2019 в 05:24
поделиться

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

  • Подкласс можно рассматривать как его суперкласс, но никогда не в обратном направлении.

Говоря более абстрактно:

public class HarleyExample
{
    static public void Test()
    {
        Motorcycle a = new Motorcycle();
            HarleyDavidson b = new HarleyDavidson();
            Motorcycle c = new Motorcycle(); //Just a plain motorcycle
            a = b; // A Harley can be treated as a regular motorcycle
            //b = a; // Not just any motorcycle is a Harley

            Console.WriteLine("Is A a motorcycle?  " + (a is Motorcycle)); 
            Console.WriteLine("Is A a harley?      " + (a is HarleyDavidson));
            Console.WriteLine();
            Console.WriteLine("Is B a motorcycle?  " + (b is Motorcycle));
            Console.WriteLine("Is B a harley?      " + (b is HarleyDavidson));
            Console.WriteLine();
            Console.WriteLine("Is C a motorcycle?  " + (c is Motorcycle));
            Console.WriteLine("Is C a harley?      " + (c is HarleyDavidson));

            Console.ReadKey();
    }
}

public class Motorcycle
{
    public void Cruise()
    {
        Console.WriteLine("Cruising");
    }
}

public class HarleyDavidson : Motorcycle
{
    public void CruiseInStyle()
    {
        Console.WriteLine("Cruising in style on a Harley");
    }
}
4
ответ дан 18 December 2019 в 05:24
поделиться

A is not implicitly convertible to B. B is convertible to A.

In

foo = bar

it's going to try to convert 'bar' to the type of 'foo'.

(That is, I think you are just misinterpreting how 'assignment' works with regards to implicit conversions.)

1
ответ дан 18 December 2019 в 05:24
поделиться

This has little to do with C#; it's basic inheritance. a is not of type BClass. What if BClass had additional fields/properties? What happens when you attempt to access one of those members on a?

1
ответ дан 18 December 2019 в 05:24
поделиться

Because all instances of BClass are also AClass since BClass inherits from AClass. AClass is less specific than BClass hence you can implicitly convert from B to A

1
ответ дан 18 December 2019 в 05:24
поделиться

BClass is a subclass of AClass (or AClass is a superclass of BClass), and the subclass relationship is an "is a" relationship. So if b is an instance of BClass, it is also an instance of AClass. This is why it is fine to point to b with the variable a, but it is not OK to point to a with b, because that requires an additional assumption.

1
ответ дан 18 December 2019 в 05:24
поделиться

Sort of paraphrasing what everyone else had said. I don't know if this makes it any clearer for you.

'a' is declared as an object of type AClass which supports the AMethod() method.

'b' is declared as an object of type BClass which supports the BMethod() method and, being a subclass of AClass, will also support the AMethod() method as it inherits it from its parent superclass.

So you can easily assign an object of type BClass to a variable of type AClass as the compiler will expect to only ever call AMethod() on it which is fine.

However, you can't assign an object of type AClass to a variable of type BClass as the compiler might expect to have to call either AMethod() or BMethod() on it and, of course, it won't be able to do the latter as an AClass object just won't support it.

1
ответ дан 18 December 2019 в 05:24
поделиться

Возможно, вы запутались, что есть что, поскольку ваш вопрос спрашивает «Почему разрешено неявное преобразование суперкласса в подкласс?» .

На самом деле, все наоборот. Подкласс - это экземпляр суперкласса, но не наоборот, поэтому типы несовместимы.

Представьте себе очень маленький суперкласс с единственным методом или константой. Теперь представьте подкласс, который определяет все, включая кухонную раковину. Это практически совершенно разные виды. Однако подкласс по-прежнему является экземпляром суперкласса; у него есть этот метод или константа.

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

1
ответ дан 18 December 2019 в 05:24
поделиться
Другие вопросы по тегам:

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