抽像类与接口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽像类与接口相关的知识,希望对你有一定的参考价值。

 

接口和抽像类都不能被实例化。只允许通过继承来使用

 

接口和抽像类比较

  接口 抽像类
属性 支持 支持
实体方法 NO 支持
抽像方法 NO   支持
虚方法 NO 支持
字段 NO 支持
事件 支持 支持
索引器 NO 支持

 

 

 

 

 

 

 

实现接口的抽象类可以将接口方法映射到抽象方法上。 例如:

interface I
{
    void M();
}
abstract class C : I
{
    public abstract void M();
}

 

接口可以多继承,抽像类只能单继承

 

接口内部,属性、接口方法、都不允许有修饰符。默认是PUBLIC

 

抽像类:

    abstract class MyAbstract
    {

        private string[] name = new string[2];

        //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
        public string this[int index]
        {
            //实现索引器的get方法
            get
            {
                if (index < 2)
                {
                    return name[index];
                }
                return null;
            }

            //实现索引器的set方法
            set
            {
                if (index < 2)
                {
                    name[index] = value;
                }
            }
        }


        /// <summary>
        /// 事件
        /// </summary>
        event Action<string> ClickEvent;

        /// <summary>
        /// 字段
        /// </summary>
        string Address = "";

        /// <summary>
        /// 属性
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 方法
        /// </summary>
        /// <returns></returns>
        public string GetName()
        {
            return "my Name";
        }
        /// <summary>
        /// 抽像方法
        /// </summary>
        /// <returns></returns>
        public abstract string GetName2();
        /// <summary>
        /// 虚方法
        /// </summary>
        /// <returns></returns>
        public virtual string GetName3()
        {
            return "22";
        }
    }

 

 接口:

   public interface MyInterface
    {

        /// <summary>
        /// 事件
        /// </summary>
        event Action<string> ClickEvent;

        /// <summary>
        /// 属性
        /// </summary>
        int Age { get; set; }

        /// <summary>
        /// 方法
        /// </summary>
        /// <returns></returns>
        string GetName();

    }

 

组合类:

使用:

            Person p = new Person();
            p.Age = 20;
            p.Name = "王某某";

 

类代码:

    /// <summary>
    /// 组合类
    /// </summary>
    public partial class Person
    {
        public int Age { get; set; }
    }

    /// <summary>
    /// 组合类
    /// </summary>
    public partial class Person
    {
        public string Name { get; set; }
    }

 

组合类的名字相同,用 partial 来修饰

WEB页面中。广泛使用 partial 

抽像类的实现:

 public class AbstractExample : MyAbstract
    {
        int age = 0;

        /// <summary>
        /// 重写虚方法
        /// </summary>
        public override int Age2
        {
            get
            {
                return age;
            }

            set
            {
                age = value;
            }
        }

        /// <summary>
        /// 覆盖父类 void Name(string name) 方法
        /// </summary>
        /// <param name="name"></param>
        public new void Name1(string name)
        {
            Console.WriteLine("my Name1 is {0},普通方法", name);
        }

        /// <summary>
        /// 重写抽像方法 abstract void Name2(string name);
        /// </summary>
        /// <param name="name"></param>
        public override void Name2(string name)
        {
            Console.WriteLine("my Name2 is {0},抽像方法", name);
        }

        /// <summary>
        /// 重写虚方法 virtual void Name3(string name)
        /// </summary>
        /// <param name="name"></param>
        public override void Name3(string name)
        {
            base.Name3(name);
            Console.WriteLine("child,my Name3 is {0},虚方法", name);
        }
    }

 

抽像类的使用:

            ///使用抽像类来定义
            MyAbstract abstractexample = new AbstractExample();

            Console.WriteLine("abstractexample.Age={0}", abstractexample.Age);
            Console.WriteLine("abstractexample.Age2={0}", abstractexample.Age2);
            abstractexample.Name1("张某某");
            abstractexample.Name2("赵某某");
            abstractexample.Name3("李某某");

            Console.WriteLine("------------------------------------");

            ///使用派生类来定义
            AbstractExample abstractexample2 = new AbstractExample();
            abstractexample2.Name1("张某某");
            abstractexample2.Name2("赵某某");
            abstractexample2.Name3("李某某");

结果图:

注意图中的两个划线,如果用抽像类来定义、那么用 new 重写的方法将不生效。仍然执行父类方法。

如果用 派生类来定义。new 重写将生效。

 

接口实现类:

 public class InterfaceExample : MyInterface
    {
        int age = 0;
        /// <summary>
        /// 接口实现了属性
        /// </summary>
        public int Age
        {
            get
            {
                return age;
            }

            set
            {
                age = value;
            }
        }
        /// <summary>
        /// 接口实现了事件 
        /// </summary>
        public event Action<string> ClickEvent;

        /// <summary>
        /// 接口实现了方法
        /// </summary>
        /// <returns></returns>
        public void GetName(string name)
        {
            Console.WriteLine("my name is {0}", name);
        }
    }

接口实现类的使用:

            MyInterface interfaceexample = new InterfaceExample();
            interfaceexample.Age = 30;
            ///调用了接口中的属性
            Console.WriteLine("abstractexample.Age={0}", interfaceexample.Age);

            ///实现了接口中的事件
            interfaceexample.ClickEvent += (s) => Console.WriteLine(s);
            ///调用了接口中的方法
            interfaceexample.GetName("贺同学");

 

override 的3个使用场景

1、abstract(抽像方法)

2、virtual(虚方法)

3、自身

以上是关于抽像类与接口的主要内容,如果未能解决你的问题,请参考以下文章

接口和类的区别

C# 中基类,虚类,抽象类,密封类,接口的区别

Python全栈之路系列----之-----面向对象4接口与抽象,多继承与多态)

解释器模式

Loader详解

JAVA接口详细讲解