不要在对抽象类接口abstract virtual什么的混淆不清了

(最近带一个新手入门 讲这边老费力了。)

接口和抽象类不过都是类的抽象罢了,这是他们的本质,只不过人们的思维角度不同而已,一个偏向为行为契约上的抽象(接口) 一个更像大自然中的繁衍关系(抽象类)。

直接上代码:

class 抽象类
    {
        public static void Main(string[] args)
        {
            ChinesePerson c = new ChinesePerson("xx", 23);
            c.Run();
            c.Speak();
            Console.WriteLine(c.Name);
            Console.WriteLine(c.Age);
            Console.WriteLine(c.Hobby);
            Console.WriteLine("--------");
            c.fight();
            JiangSuPerson j = new JiangSuPerson();
            j.Name = "xiaomao";
            j.Age = 24;
            j.Run();
            j.Speak();
            j.fight();
            j.sing();
            Console.WriteLine(j.Name);
            Console.WriteLine(j.Age);
            Console.WriteLine(j.Hobby);
            Console.WriteLine("----------");
            HenanPerson h = new HenanPerson();
            h.Name = "linyi";
            h.Speak();
            h.fight();
            h.sing();
            Console.ReadKey();
        }
    }

    public interface IRun
    {
        void Run();
    }

  public abstract class Person : IRun
    {
        private string name;
        private int age;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        public abstract string Hobby { get; set; }
        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }
        public Person()
        { }
        public abstract void Speak();
        public void Run()
        {
            Console.WriteLine("Running ~~");
        }
        //能够被子类重写的 只有 abstract 或virtual修饰的,
        //不同在于,abstract一定要被重写,而virtual则是可以被重写 但不一定非要重写,还有就是virtual要有方法体。
        public virtual void fight()
        {
            Console.WriteLine("fighting");
        }
    }
    public class ChinesePerson : Person
    {

        public ChinesePerson(string name, int age)
            : base(name, age)
        {
            this.Name = name;
            this.Age = age;
        }
        public ChinesePerson()
        {
        }
        public override void Speak()
        {
            Console.WriteLine("中国人说中文");
        }

        public override string Hobby
        {
            get
            {
                return "shopping";
            }
            set
            {
            }
        }
        public override void fight()
        {
            base.fight();
            Console.WriteLine("chinese gongfu fighting");
        }
        public virtual void sing()
        {
            Console.WriteLine("用中文唱歌");
        }
    }

 //继承自中国人,但是没有任何重写
    public class JiangSuPerson : ChinesePerson
    {

    }
    public class HenanPerson : ChinesePerson
    {
        public override void Speak()
        {
            Console.WriteLine("河南人说河南方言");
        }
        public override void sing()
        {
            Console.WriteLine("用河南话唱歌");
        }
    }

总结一下:抽象类 和接口都是类的抽象,接口更关注从行为方面来抽象,而在语法上 接口的内容必须都是没有实现的,完全等待后面的类来实现的
而在这一点上,抽象类则像是一个没有完全实现的类,他想所有普通类一样,可以拥有字段,属性,以及方法,这些都是可以有具体实现体的,
但就这样的话,他和普通类的差别只在于他不可以通过new实例化,而他的真正不同在于 他应该有abstract修饰的部分,这部分没有具体实现,必须由
由后面的实现类来具体实现。
而virtual关键字本不该属于这里的讨论范畴,他修饰的方法和普通方法几乎一样,都是有着方法体的,但是被virtual修饰的可以被子类重写。

再举个例子模拟下mvc的控制器模块

 //大致模拟了MVC框架中的控制器模块的思想
    class 抽象类二
    {
        public static void Main(string[] args)
        {
            IController ic;
            ic = new HomeController();
            ic.Execute();
            Console.ReadKey();
        }
    }

    public interface IController
    {
        void Execute();
    }

    public abstract class ControllerBase : IController
    {
        //可以选择性的重写这整个方法,而不按照所期望的分步骤
        public virtual void Execute()
        {
            Console.WriteLine("doing some unimporting things");
            ExecuteCore();
        }
        //这个方法则必须实现
        public abstract void ExecuteCore();
    }
    public abstract class Controller : ControllerBase
    {
        public override void ExecuteCore()
        {
            Console.WriteLine("doing some importing things");
        }

        //public override void Execute()
        //{
        //    Console.WriteLine("doing the whole things");
        //}
    }
    public class HomeController : Controller
    {

    }
时间: 2024-12-01 09:42:02

不要在对抽象类接口abstract virtual什么的混淆不清了的相关文章

抽象类(abstract class)和 接口(interface)

PHP中的 抽象类(abstract class)和 接口(interface) 一. 抽象类abstract class 1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类. 2 .抽象类不能被直接实例化.抽象类中只定义(或部分实现)子类需要的方法.子类可以通过继承抽象类并通过实现抽象类中的所有抽象方法,使抽象类具体化. 3 .如果子类需要实例化,前提是它实现了抽象类中的所有抽象方法.如果子类

[Java] 接口(Interface)与 抽象类 (Abstract)使用规则和区别

接口(Interface) 是抽象方法的集合,接口通常以interface来声明. 一个类通过继承接口的方式,从而来继承接口的抽象方法. 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念. 类描述对象的属性和方法.接口则包含类要实现的方法. 除非实现接口的类是抽象类,否则该类要定义接口中的所有方法. 接口无法被实例化,但是可以被实现.一个实现接口的类,必须实现接口内所描述的所有方法(所有方法都是抽象的方法),否则就必须声明为抽象类. 接口没有构造方法,支持多重继承,不能包含成员变量

面向对象_06【抽象类:abstract、接口:interface、实现:implements】

抽象类:abstract抽象:没有足够的描述功能,事物不具体的描述,却又有共性. 特点: 1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类也必须被abstract修饰. 2,抽象类不能被实例化. 3,抽象类必须有其子类覆盖所有的抽象方法后,该子类才可以实例化,否则该子类还是抽象类. 抽象类细节常见问题: 1,抽象类中有构造函数吗? 有,用于给子类对象进行初始化 2,抽象类可以不定义抽象方法吗? 可以,但是少见,目的就是不让该类创建对象.

抽象类(abstract class)和接口(Interface)的区别

前言 抽象类(abstract class)和接口(Interface)是Java语言中对于抽象类定义进行支持的两种机制,赋予了Java强大的面向对象能力. 二者具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstractclass和Interface的选择显得比较随意.其实,两者之间还是有很大的区别的. 本文将对它们之间的区别进行剖析,并提供一个在二者之间进行选择的依据. 抽象类是什么? 本文中的抽象类表示的是一个抽象体,并非直接从abstract class翻译而

虚函数/纯虚函数/抽象类/接口/虚基类

1.多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 在Java中,没有指针,就直接用父类实例化子类对象 多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的,多态可以让父类的指针有“多种形态”,这是一种泛型技术. 所谓泛型技术,就是试图使用不变的代码来实现可变的算法 2.虚函数 在基类的类定义中,定义虚函数的一般形式: Virtual 函数返回值类型 虚函数名(形参表){ 函数

Java实训笔记(二)——-抽象类-接口-泛型-集合

1.1方法的可变参数从JDK1.5之后,定义方法时参数的个数可以变化语法:最后一个数据类型后增加3个点注意:1.可变参数只能处于参数列表的最后:2.一个方法中最多只能包含一个可变参数:3.可变参数的本质就是一个数组,因此在调用一个包含可变参数的方法时,既可以传人多个参数,也可以传入一个数组.1.2装箱与拆箱基本数据类型与对应的封装类之间能够自动进行转换,其本质是Java的自动装箱与拆箱过程.-装箱是指将基本类型数据值转换成对应的封装类对象,即将栈中的数据封装成对象存放到堆中的过程.-拆箱是装箱的

抽象类-接口--抽象方法几点解释

//abstract class和interface有什么区别?含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的.abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,(抽象类中的普通方法,可以不必实现.)所以,不能有抽象构造方法或抽象静态方法.如果子类没有实现抽象父类中的所有抽 象方法,那么子类也必须定义

抽象类(abstract)【转】

抽象类(abstract) abstract修饰符可以和类.方法.属性.索引器及事件一起使用.在类声明中使用abstract修饰符以指示某个类只能是其它类的基类.标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现. è     抽象类不能实例化 è     抽象类可以包含抽象方法和抽象访问器 è     不能用sealed修饰符修改抽象类,这意味着抽象类不能被继承 è     从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实现 看一段代码: using System 

12-14java面向对象之抽象类&接口

抽象类 1.抽象类概念 抽象类:包含抽象方法的类,相比于普通类,他多了一个抽象方法. 抽象方法:只声明但是没有实现的方法,用abstract关键字来定义. 未实现的举例: class A { private String name ; public void print() } 在类中声明的方法,有{}则说明有方法体,则实现:没有{},则未实现. 2.使用规则 包含一个抽象方法的类必须是抽象类 抽象类和抽象方法都使用abstract关键字声明 抽象方法只需要声明不需要实现 抽象类必须被子类继承,