Abstract(抽象)

谈到抽象,就先谈谈面向对象语言的三大特性,也是人们口中常说的封装、继承、多态。

封装:什么是封装,按到我的理解,封装就是把某些类的相关属性和方法封装,对内实现数据影城,对外提供稳定接口。

继承:从字面上理解,就是声明一个父类,然后子类可以继承,并且子类拥有父类的一切属性和方法。

多态,值一个类实例相同的方法不同情形有不同表现形式

讲完这些说说主题,抽象类和接口。

先来说说抽象类:

1)抽象类的本质还是一个类,里面可以包含一切类可以包含的
2)抽象成员 必须包含在抽象类里面,抽象类还可以包含普通成员
3)继承抽象类后,必须显示的override其抽象成员
4)抽象类不能直接实例化,声明的对象只能使用抽象类里的方法,不能用子类新增的方法
5)父类只有一个

比如说声明一个手机的抽象类,手机又打电话,品牌,系统等一些基本属性。

public abstract class BasePhone
    {
        public int Id { get; set; }
        public string Name = "123";
        public delegate void DoNothing();
        public event DoNothing DoNothingEvent;

        public void Show()
        {
            Console.WriteLine("这里是Show1");
        }
        public virtual void ShowVirtual()
        {
            Console.WriteLine("这里是Show");
        }

        /// <summary>
        /// 品牌
        /// </summary>
        /// <returns></returns>
        public abstract string Brand();

        /// <summary>
        /// 系统
        /// </summary>
        /// <returns></returns>
        public abstract string System();

        /// <summary>
        /// 打电话
        /// </summary>
        public abstract void Call();

        /// <summary>
        /// 拍照
        /// </summary>
        public abstract void Photo();

        public abstract void Do<T>();
    }

然后有一台苹果手机;应该怎么做呢,这时候就可以继承这个抽象类。

    public class iPhone : BasePhone
    {
        /// <summary>
        /// 品牌
        /// </summary>
        /// <returns></returns>
        public override string Brand()
        {
            return "iPhone";
        }

        /// <summary>
        /// 系统
        /// </summary>
        /// <returns></returns>
        public override string System()
        {
            return "IOS";
        }

        /// <summary>
        /// 打电话
        /// </summary>
        public override void Call()
        {
            Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
        }

        /// <summary>
        /// 拍照
        /// </summary>
        public override void Photo()
        {
            Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
        }

        public override void Do<T>()
        {

        }

    }

那如果这台手机需要实现一个支付功能呢,怎么办,可以在苹果手机类中添加一个支付功能,但是手机不只是有苹果,还有别的品牌,如果都有支付功能,不可能在每个类中都添加一个这样的方法吧,这样太麻烦了,有人会讲,在抽象类中抽象一个支付方法,但是在抽象类中添加了方法,所有继承了这个类的都需要实现这个方法,这样太不方便了,这个时候就需要接口。

1)接口不是类,里面可以包含属性、方法、事件 不能包含字段,委托,不能用访问修饰符

2)接口只能包含没有实现的方法

3)实现接口的话,必须实现全部方法

4)接口不能直接实例化,声明的对象只能使用接口里的方法,不能用子类新增的方法

5)接口可以实现多个

public interface IPay
    {
        void Pay();
    }

这样在苹果类实现这个接口,就既可以实现支付功能,又不会影响其他类。

   public class iPhone : BasePhone,  IPay
    {
        /// <summary>
        /// 品牌
        /// </summary>
        /// <returns></returns>
        public override string Brand()
        {
            return "iPhone";
        }

        /// <summary>
        /// 系统
        /// </summary>
        /// <returns></returns>
        public override string System()
        {
            return "IOS";
        }

        /// <summary>
        /// 打电话
        /// </summary>
        public override void Call()
        {
            Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
        }

        /// <summary>
        /// 拍照
        /// </summary>
        public override void Photo()
        {
            Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
        }

        public override void Do<T>()
        {

        }

        public void Pay()
        {
            throw new NotImplementedException();
        }
    } 

说了这么多。那么什么时候用抽象类,什么时候用接口呢

抽象是模板化,减少一定的代码量;

接口是功能化,增加一定的灵活性;

用经典的话说,就是is a,和has a 的关系。

抽象类本质还是一个类,就好比上面举的例子,BasePhone这个类他的本质还是是一份手机,只不过是把手机一些共有的性能给抽象出来一个类。

在比如IPay这个接口,它只是为了手机拥有这个功能而存在的,但不是所有的手机都拥有了这个功能,所以说只能把支付功能声明为一个接口。

最后说说重写overwrite(new)  覆写override 重载overload(方法)

在这里就不细说了,直接通过代码是讲述。

声明一个父类:有普通方法,虚方法,抽象方法,然后子类继承,

#region abstract
    public abstract class ParentClass
    {
        /// <summary>
        /// CommonMethod
        /// </summary>
        public void CommonMethod()
        {
            Console.WriteLine("ParentClass CommonMethod");
        }

        /// <summary>
        /// virtual  虚方法  必须包含实现 但是可以被重载
        /// </summary>
        public virtual void VirtualMethod()
        {
            Console.WriteLine("ParentClass VirtualMethod");
        }

        public abstract void AbstractMethod();
    }

    public class ChildClass : ParentClass
    {
        /// <summary>
        /// new 隐藏
        /// </summary>
        public new void CommonMethod()
        {
            Console.WriteLine("ChildClass CommonMethod");
        }
        /// <summary>
        /// virtual 可以被覆写
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override void VirtualMethod()
        {
            Console.WriteLine("ChildClass VirtualMethod");
            base.VirtualMethod();
        }

        public override void AbstractMethod()
        {
            Console.WriteLine("ChildClass AbstractMethod");
        }
    }

    #endregion abstract

 通过控制台程序看效果。 

class Program{
 static void Main(string[] args)
        {
   Console.WriteLine("*******************************************");
                     Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            ParentClass instance = new ChildClass();
            Console.WriteLine("下面是instance.CommonMethod()");
            instance.CommonMethod();
            Console.WriteLine("下面是instance.VirtualMethod()");
            instance.VirtualMethod();
            Console.WriteLine("下面是instance.AbstractMethod()");
            instance.AbstractMethod();
}

}

  

可以看出普通方法,是调用父类的方法,虚方法和抽象方法都是调用子类的,其实不难理解,因为虚方法和抽象方法都被子类给override(覆写)了。

那什么是重载呢,重载就是方法名相同,参数不同

 public new void CommonMethod()
        {
            Console.WriteLine("ChildClass CommonMethod");
        }

        public void CommonMethod(string name)
        {
           Console.WriteLine("ChildClass CommonMethod");
        }
       public void CommonMethod(int id)
        {
            Console.WriteLine("ChildClass CommonMethod");
        }
        public void CommonMethod(int id, string name)
        {
            Console.WriteLine("ChildClass CommonMethod");
       }

  

时间: 2024-10-06 20:00:41

Abstract(抽象)的相关文章

abstract 抽象

如有不足,多多指导 abstract 可以修饰类,方法. 作用:强制使用多态 注意:1.抽象类中不一定有抽象方法,但抽象方法的类,一定是个抽象类 2.子类继承抽象类后,必须实现父类定义的所有抽象方法 3.在一个抽象类中 所有的属性都是公开静态常量 隐式 public static final 修饰 所有的方法都是公开抽象方法 隐式 public abstract 修饰 抽象类可以有构造函数

深入解读php中抽象(abstract)类和抽象方法

在面向对象(OOP)语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法作为外部代码访问的接口.而抽象方法就是为了方便继承而引入的,现在来看一下抽象类和抽象方法分别是如何定义以及他们的特点. 什么是抽象方法? 我们在类里面定义的只有方法名没有方法体的方法就是抽象方法,所谓没有方法体就是在方法声明的时候没有大括号以及其中的内容,而是直接声明时在方法名后加上分号结束,另外在声明抽象方法时还要加一个关键字"abstract"来修饰. 1.抽象关键字 :abstract 抽象就是无

JAVA学习--Abstract使用方法

* abstract:抽象的,可以用来修饰类.方法 *  * 1.abstract修饰类:抽象类  * 1)不可被实例化  * 2)抽象类有构造器 (凡是类都有构造器)  * 3)抽象方法所在的类,一定是抽象类.  * 4)抽象类中可以没有抽象方法.  *  * 2.abstract修饰方法:抽象方法  * 1)格式:没有方法体,包括{}.如:public abstract void eat();  * 2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法.  

尚学堂 JAVA Day13 abstract 关键字

Abstract (抽象的) 这是一个关键字. 可以且只可以 用来修饰 <类> <方法>. 1---Abstract 类 如:Animal,可以被理解一个抽象的类.动物嘛,只是人类用来区分自己和其他物种的抽象概念,并无哪个物种实际就叫Animal. 通俗来理解,我们无法在现实世界里找到一个Animal的具体对象,只能找到这个概念下某一类物种,比如孔雀,蛇,马等等. 因此,通常可以将这样没有实例的类,或者不希望其能new出对象的类,声明为abstract. 2---Abstract类

java抽象、接口 和final

抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. 3.抽象类中,可以有抽象方法,也可以有非抽象方法.抽象类中还可以有成员变量. 4.派生类中,可以不实现某些抽象方法,但派生类必须要声明为抽象类. 二.抽象方法:不知道具体是干什么事情的方法.abstract 返回类型 函数名(形参); 1.抽象方法没有函数体. 2.有抽象方法的类必须是抽象类. 遇到抽象类,两种用法: 1.找找有没有它的派生类,用它的派生

Java基础学习23(abstract)

abstract:抽象的,可以修饰类,方法 abstract不能用来修饰属性(没办法覆盖)                    构造器(不能被重写)                    private(子类是不能覆盖或者重写声明为private的方法)                    final(final不允许重写,但abstract是希望重写,所以矛盾)                    static

PHP抽象的方法及概念

一.抽象关键字 :abstract 抽象就是无法确切的说明,但又有一定的概念或者名称,在PHP中声明一个抽象类或者方法我们需要使用adstract关键字. 二.抽象方法和抽象类的定义 一个类中至少有一个方法是抽象的,我们称之为抽象类.所以如果定义抽象类首先定义抽象方法. ? 1 2 3 4 abstract class class1{   abstract function fun1(); -- } 1.类中至少有一个抽象方法2.抽象方法不允许有{ }3.抽象方法前面必须要加abstract 三

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

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

如果将一个类设置为abstract,则此类必须被继承使用

利用final定义方法:这样的方法为一个不可覆盖的方法. Public final void print(){}: 为了保证方法的一致性(即不被改变),可将方法用final定义. 如果在父类中有final定义的方法,那么在子类中继承同一个方法. 如果一个方法前有修饰词private或static,则系统会自动在前面加上final.即private和static方法默认均为final方法. 注:final并不涉及继承,继承取决于类的修饰符是否为private.default.protected还是

final与abstract关键字

final特点: 1:这个关键字是一个修饰符,可以修饰类,方法,变量. 2:被final修饰的类是一个最终类,不可以被继承. 3:被final修饰的方法是一个最终方法,不可以被覆盖. 4:被final修饰的变量是一个常量,只能赋值一次.   其实这样的原因的就是给一些固定的数据起个阅读性较强的名称. 不加final修饰不是也可以使用吗?那么这个值是一个变量,是可以更改的.加了final,程序更为严谨.常量名称定义时,有规范,所有字母都大写,如果由多个单词组成,中间用 _ 连接.   抽象类: a