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

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

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

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

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

先来说说抽象类:

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");
}

  

Abstract(抽象)的更多相关文章

  1. 抽象鸡类 abstract(抽象) base(基础) class(类型)

    # --> ''' class interface 接口: 建立关联的桥梁, 方便管理代码 (python中没有接口语法) 接口类: 用来定义功能的类 为继承它的子类提供功能 该类的功能法方法一 ...

  2. abstract抽象

    abstract:抽象 是用来修饰抽象类和抽象方法的 那么什么抽象,抽象有究竟有什么用呢?? 我们知道,“类”是某一类具有相同特征或行为的物事,是将这些物事特征向上抽取得来的:“父类”也是子类不断向上 ...

  3. php中关于抽象(abstract)类和抽象方法的问题解析

    在面向对象(OOP)语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法作为外部代码访问的接口.而抽象方法就是为了方便继承而引入的,现在来看一下抽象类和抽象方法分别是如何定义以及他们的特点 ...

  4. java抽象、接口 和final

    抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. public abstract class USB { ...

  5. java中abstract详解

    Abstract(抽象)可以修饰类.方法 如果将一个类设置为abstract,则此类必须被继承使用.此类不可生成对象,必须被继承使用. Abstract可以将子类的共性最大限度的抽取出来,放在父类中, ...

  6. 基础知识系列☞Abstract和Virtual→及相关知识

    转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...

  7. 尚学堂 JAVA Day13 abstract 关键字

    Abstract (抽象的) 这是一个关键字. 可以且只可以 用来修饰 <类> <方法>. 1---Abstract 类 如:Animal,可以被理解一个抽象的类.动物嘛,只是 ...

  8. 三大修饰符static,final,abstract,接口和抽象类的区别

    package com.cityhero.test; public class ThreeModifier { //static静态的 // 概念:static可以修饰方法和属性,被static修的方 ...

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

    抽象类:abstract抽象:没有足够的描述功能,事物不具体的描述,却又有共性. 特点: 1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类也 ...

  10. 逆袭之旅.DAY07东软实训..封装~继承~抽象~final

    2018年7月3日.逆袭之旅DAY07 package day0703.exam1; /** * 狗狗类 使用权限修饰符private和public进行封装 * @author Administrat ...

随机推荐

  1. Cocos2d-X 3.2环境的配置

    大三寒假时间特别长,终于准备坐下来好好去学一直想涉足的游戏开发.既然准备学,就要找个出色的.跨平台的引擎来实现自己的计划.最终我选定了Cocos2d-X. 在折腾了很久之后,我终于把Cocos2d-X ...

  2. tensorflow图像基本处理

    tensorflow库提供的专门的图片处理库,以下只是部分示例,更多函数请参照源码'\tensorflow_api\v1\image__init__.py' 加载图像 方式1: 使用tf.gfile. ...

  3. const in C/C++

    1.const 对象必须初始化,因为一旦创建后值不能改变. Eg: const int i = GetSize(); //正确:运行时初始化 const int j = 42;   //正确:编译时初 ...

  4. Hash学习小结

    Hash 简要说明 \(OI\)中一般采用进制\(hash\).模数可以用\(unsigned \ long \ long\)自然溢出,也可以使用大质数.值得一提的是,\(unsigned\ long ...

  5. BZOJ1096 ZJOI2007 仓库建设 【斜率优化DP】

    BZOJ1096 ZJOI2007 仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般 ...

  6. Python学习-赋值、浅copy和深copy

    Python Copy: 在Python语言中,分为浅拷贝和深拷贝两种形式,也就是官方文档中的Shadow copy和Deep copy.在对简单的对象(object)进行复制时,两者没有区别,如下面 ...

  7. 图像对比度调整的simulink仿真总结

    图像对比度调整可以由一个模块contrast adjustment 完成,参数有输入范围和输出范围,计算过程由以下公式决定 解释一下,当input<=low_in的时候输出的值是low_out+ ...

  8. quick code ide设置分辨率

    默认是640*960的分辨率,但是我的设计分辨率是480*800 所以得改改 在config.lua里的改成 -- design resolutionCONFIG_SCREEN_WIDTH = 480 ...

  9. [Oracle] CPU/PSU补丁安装详细教程

    Oracle CPU的全称是Critical Patch Update, Oracle对于其产品每个季度发行一次安全补丁包,通常是为了修复产品中的安全隐患,以下是对CPU/PSU补丁安装的具体操作步骤 ...

  10. Ubuntu 16.04 配置安卓5.1编译环境

    Ubuntu 16.04版本 电脑cpu必须是64位 硬盘分配大约100G的空间 1.ubuntu中更新源 $ sudo apt-get update 2.安装 openjdk-8-jdk $ sud ...