Есть ли способ вызвать реализацию метода самого подкласса? - PullRequest
0 голосов
/ 24 января 2019

В моей игре я делаю единство, у меня есть абстрактный суперкласс SpaceshipController, и он содержит реализованный метод protected void updateSpaceshipMovement().Для каждого космического корабля существует подкласс, и в некоторых из них метод переопределяется (protected new void updatePlayerMovement()).Метод, когда вызывается в суперклассе, использует реализацию SpaceshipController, и я хотел знать, есть ли способ вызвать реализацию в подклассах, когда метод вызывается в коде суперкласса.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Чтобы ответить на вопрос:

Нет, не так, как вы это реализовали.

Как базовый класс должен знать, что где-то есть унаследованный класс, у которого есть метод, который перезаписывает его метод и должен вызываться вместо него?


Вы должны правильно наследовать (override) метод, используя ключевое слово virtual. Чтобы показать разницу, я также добавил метод abstract.

public abstract class SpaceshipController 
{
    // already has an implementation but might be extended or overruled
    protected virtual void updateSpaceshipMovement()
    {
        // do something general
    }

    // does not have an implementation -> HAS to be implemented by subclass
    protected abstract void Something();
}

Если нет методов abstract, вам может даже не понадобиться делать базовый класс abstract.

Теперь в подклассе override метод virtual. (И реализовать abstract из них.)

public class ExampleController : SpaceshipController 
{
    // I don't have to implement updateSpaceshipMovement
    // but I want to extend or overwrite it
    protected override void updateSpaceshipMovement()
    {
        // optional: anyway execute base code
        base.updateSpaceshipMovement();

        // do other stuff
    }

    // I have to implement this
    protected override void Something()
    {
        // do something
    }
}
  • virtual означает:
    Метод уже имеет реализацию в базовом классе, но может быть переписан в любом случае или расширен с использованием base.method()

  • abstract означает:
    В базовом классе нет реализации => должен быть реализован подклассом.


В случае, если все подклассы должны иметь свою собственную реализацию и вообще не использовать base.updateSpaceshipMovement, возможно, интерфейс может быть даже лучше:

public interface ISpaceshipController
{
    void updateSpaceshipMovement();
}

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

Реализуйте это, например. как

public class ExampleController : MonoBehaviour, ISpaceshipController
{
    // I have to implement this to fulfill the interface implementation
    public void updateSpaceshipMovement()
    {
        // do stuff
    }
} 
0 голосов
/ 24 января 2019

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

В SpaceshipController измените protected void updateSpaceshipMovement() на protected virtual void updateSpaceshipMovement(). Это говорит компилятору использовать эту реализацию по умолчанию для SpaceshipController и любых подклассов.

В вашем подклассе измените protected new void updatePlayerMovement() на protected override void updatePlayerMovement(). Это говорит компилятору использовать эту модифицированную реализацию для этого конкретного класса.

protected override void updatePlayerMovement(){
  base.updatePlayerMovement(); //you can also call the parent implementation first if you so choose.
  //now perform the actions specific to this sub class.

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...