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

0
Isaac Phillips 15 Авг 2019 в 05:52

2 ответа

Лучший ответ

Расширение ответа Draco18s Я думаю, что вы хотели спросить:

Может ли class, который наследует от MonoBehaviour, также внедрить interface? - Да, конечно! В этом вся идея наличия интерфейсов: класс может только наследовать от точно одного родительского класса. Интерфейсы, однако, позволяют классу «наследовать» несколько наборов методов. Классический пример:

Существует родительский тип Boat.
Тогда есть унаследованные типы: SailBoat : Boat и MotorBoat : Boat.
А что вы будете делать, если вам нужен SailBoat с двигателем? Вместо того, чтобы определять все дважды, вы создаете интерфейсы ISailBoat и IMotorBoat, создаете новый класс и позволяете ему реализовать оба интерфейса MotorSailBoat : Boat, ISailBoat, IMotorBoat.

Преимущество: этот тип теперь можно использовать как ISailBoat или IMotorBoat, например, он может появляться в списках обоих типов.

Создать интерфейс на основе существующего класса

Могу ли я преобразовать существующий класс MonoBehaviour в интерфейс? - Ну, скажем, у вас есть класс

public class AnAwesomeBehaviour : MonoBehaviour
{
    public void DoSomethingAwesome()
    {
        Debug.Log("Are you not entertained!?");
    }
}

Поэтому для создания интерфейса просто создайте новый интерфейс с соответствующими сигнатурами методов.

interface IMyAwesomeInterface
{
    // interface methods are automatically PUBLIC
    void DoSomethingAwesome();
}

И пусть ваш MonoBehaviour реализует этот интерфейс.

public class AnAwesomeBehaviour : MonoBehaviour, IMyAwesomeInterface
{
    public void DoSomethingAwesome()
    {
        Debug.Log("Are you not entertained!?");
    }
}

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


Наследование

Если у вас есть свой оригинальный class и вы просто хотите расширить его с помощью дополнительных методов, но при этом можете также использовать оригинальный на > э ... это то, что называется наследование :

public class AnAwesomeBehaviour : MonoBehaviour
{
    public void DoSomethingAwesome()
    {
        Debug.Log("Are you not entertained!?");
    }
}

public class AnEvenMoreAwesomeBehaviour : AnAwesomeBehaviour 
{
    public void DoSomethingAwesomeButWithParamters(string horse)
    {
        Debug.Log($"Look at my {horse}, my {horse} is amazing!");
    }
}

Этот новый класс AnEvenMoreAwesomeBehaviour теперь может выполнять как DoSomethingAwesome (который он унаследовал), так и DoSomethingAwesomeButWithParamters(string), который он реализовал.


Абстрактный класс

Наконец, у вас есть «сочетание» обоих в {{X0 } }. Такой класс является просто шаблоном и сам по себе никогда не создавался . Однако вы можете наследовать его и создавать новые классы на основе его функциональных возможностей:

// inherits from MonoBehaviour -> already implements the full functionality
// of MonoBehaviors
public abstract class AnAwesomeBehaviour : MonoBehaviour
{
    // it can have some fields all inheritors shall have
    // everyone will have access to this
    public string Horse;

    // only this class and inheritors will have access to this
    protected int amountOfHorses;

    // only this class has access to this
    private Camera _camera;


    // The same can be done for methods
    // But there are now special methods

    // a virtual method already has its own implementation
    // but can be overwritten or extended by inheritors
    protected virtual void Start()
    {
        _camera = Camera.main;

        Debug.Log("On Start I usually do nothing special with the " + _camera.name);
    } 

    // an abstract method kind of works like an interface
    // every inheritor HAS TO implement this method exactly with the same 
    // signature
    public abstract void DoYourThing(string value);

    // and you still can implement some default behaviours that every
    // inheritor will just do
    private void Update()
    {
        // rotate the object forever
        transform.Rotate(0, Time.deltaTime * 45, 0);
    }
}

Теперь вы можете использовать этот абстрактный шаблон и создавать свои классы из него

public class AnAwesomeCountBehaviour : AnAwesomeBehaviour 
{
    // I have to implement this
    public override void DoYourThing(string value)
    {
        Horse = value;
        Debug.Log($"Look I now have {amountOfHorses} {Horse}" + (amountOfHorses == 1 ? "" : "s"));
    }

    // and optionally CAN extend or overwrite this
    protected override void Start()
    {
        //also optional first execute whatever the original implementation does
        base.Start();

        // now add my own stuff
        Debug.Log($"First I had {amountOfHorses} {Horse}" + (amountOfHorses == 1 ? "" : "s"));
    }
} 

Примечание. virtual также может использоваться в неабстрактном классе, тогда как abstract может только использоваться в абстрактном классе.

3
derHugo 15 Авг 2019 в 07:48

Прямой ответ: нет

MonoBehaviour это класс. Кусок кода не может быть как интерфейсом, так и расширять класс.

Косвенный ответ: тоже нет

Если вы хотите, чтобы фрагмент кода делал что-то («отслеживание времени с помощью функции обновления»), то это не интерфейс (или абстрактный класс (сортировка)).

0
Draco18s no longer trusts SE 15 Авг 2019 в 03:00