【C#基础】chatGpt带你学C#接口,它在游戏中有什么应用?

What are Interfaces?

In computer programming, an interface is a set of rules or guidelines that define how different software components or systems should interact with each other. It serves as a contract between two or more components, specifying how they should communicate with each other without revealing the underlying implementation details.

An interface defines a standardized set of methods, properties, events, and other members that can be used by other software components or systems. By adhering to a common interface, components can communicate with each other consistently and predictably, even if they were developed by different software vendors or on different platforms.

Interfaces can be used in a variety of programming languages and technologies, including object-oriented programming, web services, and message-based systems. They are particularly useful in large, complex software systems where many different components need to work together seamlessly.

经过Grammarly的修改后再由chatGpt翻译如下:

在计算机编程中,接口是一组规则或指导方针,用于定义不同的软件组件或系统应如何相互交互。它充当两个或多个组件之间的契约,规定它们应该如何相互通信,同时不揭示底层实现细节。

接口定义了一组标准化的方法、属性、事件和其他成员,可供其他软件组件或系统使用。通过遵守共同的接口,组件可以以一种一致和可预测的方式相互通信,即使它们由不同的软件供应商或在不同的平台上开发。

接口可用于各种编程语言和技术,包括面向对象编程、Web服务和基于消息的系统。它们特别适用于大型复杂的软件系统,在这些系统中,许多不同的组件需要无缝地协同工作。

Defining Interface

在C#中,可以通过以下方式定义接口:

public interface IMyInterface
{
    // 定义方法签名,但不提供实现
    void MyMethod1();
    
    // 定义带参数的方法签名
    int MyMethod2(string input);
    
    // 定义属性,不包含实现
    string MyProperty { get; set; }
    
    // 定义事件,不包含实现
    event EventHandler MyEvent;
}

接口是一个纯抽象的概念,它定义了一组方法、属性或事件的签名,但不提供具体的实现。接口是一种规范,它定义了一个类或结构体应该实现的行为。类或结构体可以实现一个或多个接口,并提供相应的实现。在实现接口时,必须提供与接口定义相同的方法、属性或事件的实现。

Interface Implementation

接下来我们会一个一个实现上述定义。

方式一:单个 Interface
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static Testing;

public class Testing : MonoBehaviour
{
    private void Start()
    {
        MyClass myClass=new MyClass();
        TestInterface(myClass);
    }

    private void TestInterface(IMyInterface myInterface)
    {
        myInterface.TestFunction();
    }
}

public interface IMyInterface{void TestFunction();}

public class MyClass : IMyInterface
{
    public void TestFunction()
    {
        Debug.Log("MyClass.TestFunction()");
    }
}

在这里插入图片描述

方式二:Multiple Interface
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static Testing;

public class Testing : MonoBehaviour
{
    private void Start()
    {
        MyClass myClass=new MyClass();
        TestInterface(myClass);
        
        MySecondClass mySecondClass=new MySecondClass();
        TestInterface(mySecondClass);
    }

    private void TestInterface(IMyInterface myInterface)
    {
        myInterface.TestFunction();
    }
}

public interface IMyInterface{void TestFunction();}

public class MyClass : IMyInterface
{
    public void TestFunction()
    {
        Debug.Log("MyClass.TestFunction()");
    }
}

public class MySecondClass : IMyInterface
{
    public void TestFunction()
    {
        Debug.Log("MySecondClass.TestFunction()");
    }
}

在这里插入图片描述

多个接口实现
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static Testing;

public class Testing : MonoBehaviour
{
    private void Start()
    {
        MyClass myClass=new MyClass();
        TestInterface(myClass);
    }

    private void TestInterface(IMyInterface myInterface)
    {
        myInterface.TestFunction();
    }
}

public interface IMyInterface: IMySecondInterface
{ 
    void TestFunction();
}

public interface IMySecondInterface
{
    void SecondTestFunction(int i);
}

public class MyClass : IMyInterface, IMySecondInterface
{
    public void SecondTestFunction(int i)
    {

    }

    public void TestFunction()
    {
        Debug.Log("MyClass.TestFunction()");
    }
}
//下面会提示报错,因为public interface IMyInterface: IMySecondInterface没有实现相应的方法
//public class MySecondClass : IMyInterface{...}
Interface Properties

C#中,可以使用接口来定义接口属性。定义接口属性的语法类似于定义常规属性,但需要在属性声明前加上getset访问器,以指定属性的访问方式。下面是一个使用接口属性的示例:

interface IMyInterface
{
    int MyProperty { get; set; }
}

class MyClass : IMyInterface
{
    private int myPropertyValue;

    public int MyProperty
    {
        get
        {
            return myPropertyValue;
        }
        set
        {
            myPropertyValue = value;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass();
        //setter
        myClass.MyProperty = 42;
        //getter
        Console.WriteLine(myClass.MyProperty);
    }
}

在上面的代码中,IMyInterface接口定义了一个名为MyProperty的接口属性,它具有getset访问器。然后,MyClass类实现了IMyInterface接口,并提供了自己的实现来满足接口属性的要求。

MyClass类中,MyProperty属性具有一个私有字段myPropertyValue作为其实际实现,get访问器返回该字段的值,而set访问器设置该字段的值。

最后,在Main方法中,我们创建了一个MyClass对象,并将其MyProperty属性设置为42。然后,我们输出了该属性的值,这将打印出42

定义事件

在 C# 接口中定义事件的语法如下:

event EventHandler MyEvent;

其中,MyEvent 是事件的名称,EventHandler 是事件委托类型。可以根据需要使用自定义的委托类型。

在实现类中实现事件时,需要使用 addremove 关键字分别添加和移除事件处理程序。如下是实例:

public event EventHandler MyEvent
{
    add
    {
        // 在事件委托实例中添加事件处理程序
        // 这里可以添加一些逻辑,例如检查订阅者是否已经存在等等
        _myEvent += value;
    }
    remove
    {
        // 从事件委托实例中移除事件处理程序
        // 这里可以添加一些逻辑,例如检查订阅者是否存在等等
        _myEvent -= value;
    }
}
//实现事件时,通常建议使用私有事件字段来存储事件委托实例,以保证事件的封装性和安全性。
private event EventHandler _myEvent;

public void RaiseEvent()
{
    // 触发事件, 使用可空运算符 ?. 来避免空引用异常,因为可能没有任何订阅者订阅该事件。
    _myEvent?.Invoke(this, EventArgs.Empty);
}

注意:实现类必须显式实现接口中定义的事件,即使它们没有任何实现。这是因为接口事件只是一种合同,要求实现类提供事件的实现。

应用场景

以下代码忽略不需要注意的细节。

问题

假设我们创建一个(或多个)个敌人和一个(或多个)可受打击伤害的物体,在Unity中,默认创建的前者两个对象都有自己独立的C#脚本,不共享任何基类或者任何东西,再创建一个角色player,现在我们希望这名角色可以对敌人和物体造成伤害,我们会怎么做?

先写个一般人会想到的解决思路,我们创建一个飞刀类FlyCutter表示产生伤害的主体,先获取主体,每个主体中有对应的伤害函数,然后判断。

public class FlyCutter : MonoBehaviour{
    //通过物理,检查碰撞
    private void OnTriggerEnter2D(Collider2D collider){
        Enemy enemy = collider.GetComponent<Enemy>();
        if(enemy!=null){
            //造成伤害
            enemy.Damge();
        }
        
        WUPING wuping = collider.GetComponent<WUPING>();
        if(wuping!=null){
            //造成伤害
            wuping.Damge();
        } 
    }
}

创建表示可以有效被造成伤害的敌人Enemy脚本

public class Enemy : MonoBehaviour{
   	/*Enemy的主体信息*/
    
    //假设已经有伤害函数,扣血条
    public void Damage(){...}
}

还要可以被伤害的物体

public class WUPING : MonoBehaviour{
    /*WUPING的主体信息与其他额外的操作,比如打开,盗窃,陷阱等等*/
    
    public void Damage(){...}
}
以为就上面这种一个一个加,就可以了?但是但是,你还是想得太简单了!!!

如果这样干,我们岂不是要考虑所有可能被伤害的主体,换个武器会怎么样?不就重复了吗?

解决思路

  • 当问到有独立这个词时->接口
  • 角色如何对其他主体产生伤害?

于是我们可以在单独的脚本创建一个统一的伤害接口IDamageable

public interface IDamageable{
	void Damage();
}

让敌人和物体实现这个接口

public class Enemy : MonoBehaviour,IDamageable{
    public void Damage(){...}
}

public class WUPING : MonoBehaviour,IDamageable{
    public void Damage(){...}
}

现在可以让我们的飞刀变得简洁了。

public class FlyCutter : MonoBehaviour{
    //通过物理,检查碰撞
    private void OnTriggerEnter2D(Collider2D collider){
        IDamageable damageable = collider.GetComponent<IDamageable>();
        if(damageable!=null){
            //造成伤害
            damageable.Damge();
        }
    }
}

其他应用场景

当使用C#编写游戏时,接口(interface)是一种非常有用的工具,可以帮助您管理和组织代码。下面是一些游戏场景,您可以在这些场景中使用接口:

  1. 角色控制器:如果您正在编写角色控制器,可以使用接口来定义通用的方法,例如移动、攻击、受伤和死亡。每个角色都可以实现这些接口,并覆盖方法来实现特定的行为。
  2. 物品系统:如果您正在编写一个物品系统,可以使用接口来定义通用的物品接口,例如使用、丢弃和交换。这样,每个物品都可以实现这些接口,并覆盖方法来实现特定的行为。
  3. 任务系统:如果您正在编写任务系统,可以使用接口来定义通用的任务接口,例如接受、完成和失败。每个任务都可以实现这些接口,并覆盖方法来实现特定的行为。
  4. 状态机:如果您正在编写状态机,可以使用接口来定义通用的状态接口,例如进入、退出和更新。每个状态都可以实现这些接口,并覆盖方法来实现特定的行为。
  5. 网络通信:如果您的游戏需要与其他玩家或服务器通信,可以使用接口来定义通用的网络接口,例如连接、发送和接收数据。每个网络模块都可以实现这些接口,并覆盖方法来实现特定的行为。

总之,接口可以在游戏中的许多场景中发挥作用,可以帮助您更好地组织和管理代码,从而使您的游戏更易于维护和扩展。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值