using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 多态
{
class Program
{
static void Main(string[] args)
{
//员工9点打卡, 经理11点打卡,程序员不打卡
Employee emp = new Employee();
emp.Daka();
Manager man = new Manager();
man.Daka();
Programer pro = new Programer();
pro.Daka(); Console.WriteLine();
//和上面的一样
Employee[] emps = { emp, man, pro };
for (int i = 0; i < emps.Length;i++ )
{
//if(emps[i] is Manager)
//{
// ((Manager)emps[i]).Daka();
//}
//else if(emps[i] is Programer)
//{
// ((Programer)emps[i]).Daka();
//}
//else
//{
// emps[i].Daka();
//}
emps[i].Daka();
emps[i].Say();
emps[i].Speak("Hello bad cat");
} //抽象类不能创建对象,不能被实例化
//Person per = new Person(); Console.ReadKey(); } } //如果父类的方法没有默认实现,并且父类不需要被实例化
//这时可以考虑将父类定义成一个抽象类
abstract class Person
{
//抽象类不能创建对象
//抽象类中可以含有字段、实函数和虚函数等普通成员,可以不被子类重写
public string Name { get; set; }
public int Age { get; set; } public void Say()
{
Console.WriteLine("hello");
} //虚函数,可以实现,可以不实现
public virtual void Daka()
{
Console.WriteLine("virtual hello");
} //如果用户定义了自己的构造函数,而在子类继承时调用的是原先的默认的无参构造函数
//因此要再定义一个无参的构造函数
public Person(string name,int age)
{
this.Name = name;
this.Age = age;
} //抽象类有构造函数,虽然不能被实例化
public Person()
{ } //抽象类中可以具有抽象成员,并且不能是private
//抽象成员必须标记为abstract,并且不能在抽象类中实现
//抽象成员必须在抽象类中
public abstract void SayHi(); //带有参数的抽象成员
public abstract void Speak(string words);
} //子类也是抽象类,可以不实现父类的抽象成员
abstract class test:Person
{ }
//如果父类的方法有默认实现,并且父类需要被实例化
//可将父类定义成一个普通类,用虚方法实现多态
//对于继承抽象类的子类,必须将父类中的抽象成员都重写
//除非子类也是抽象类
class Employee:Person
{
//public override void Daka()
//{
// Console.WriteLine("9点打卡");
//}
//没有实现时运行Person中的virtual hello
public override void SayHi()
{ } public override void Speak(string words)
{
Console.WriteLine(words);
}
} //如果抽象类继承抽象类,并且可以不实现抽象类中的抽象函数
abstract class MyEmployee:Person
{ } class Manager : Employee
{
public override void Daka()
{
Console.WriteLine("11点打卡");
}
} class Programer : Employee
{
public override void Daka()
{
Console.WriteLine("不打卡");
}
}
}

 

总结 

1.抽象成员必须标记为abstract,并且不能有任何实现。
2.抽象成员必须在抽象类中。
3.抽象类不能被实例化

4.子类继承抽象类后,必须把父类中的所有抽象成员都重写。
(除非子类也是一个抽象类,则可以不重写)

5.抽象成员的访问修饰符不能是private

6.在抽象类中可以包含实例成员。
并且抽象类的实例成员可以不被子类实现

7.抽象类是有构造函数的。虽然不能被实例化。

8、如果父类的抽象方法中有参数,那么。继承这个抽象父类的子类在重写父类的方法的时候必须传入对应的参数。

如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候 也必须要传入返回值。

======
如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现多态。

如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类。

练习

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; /*
* 模拟将外部的移动设备查到电脑上进行读写
* U 盘read、write
*
* 移动硬盘read、write
*
* MP3 read write playmusic
*/
namespace 抽象类练习
{
class Program
{
static void Main(string[] args)
{
UDisk udisk = new UDisk();
MobileDisk mdisk = new MobileDisk();
Mp3 mp3 = new Mp3(); Computer cpu = new Computer();
cpu.ds = udisk;
cpu.CpuWrite(cpu.ds);
cpu.CpuRead(cpu.ds);
Console.WriteLine(); Telephone tel = new Telephone();
tel.ds = mdisk;
tel.TelWrite();
tel.TelRead();
Console.ReadKey();
}
} abstract class Disk
{
public abstract string Read();
public abstract void Write(string str);
} class UDisk:Disk
{
public override string Read()
{
Console.WriteLine("U Read");
string str = "U Read";
return str;
} public override void Write(string str)
{
Console.WriteLine("U write" + str);
}
} class MobileDisk:Disk
{
public override string Read()
{
Console.WriteLine("MobileDisk Read");
string str = "MobileDisk Read";
return str;
} public override void Write(string str)
{
Console.WriteLine("MobileDisk Write"+str);
}
} class Mp3:Disk
{
public override string Read()
{
Console.WriteLine("Mp3 Read");
string str = "Mp3 Read";
return str;
} public override void Write(string str)
{
Console.WriteLine("Mp3 Write"+str);
} public void PlayMusic()
{
Console.WriteLine("Mp3 is playing music");
}
} class Computer
{
public Disk ds { get; set; }
public void CpuRead(Disk disk)
{ string str = disk.Read();
//
} public void CpuWrite(Disk disk)
{ string str = "Cpu ";
disk.Write(str);
} public Computer()
{
Console.WriteLine("Cpu:");
}
} class Telephone
{
public Disk ds { get; set; }
public void TelRead()
{
string str = ds.Read();
//Console.WriteLine(str);
} public void TelWrite()
{
string str = "Tel ";
ds.Write(str);
} public Telephone()
{
Console.WriteLine("Tel:");
}
}
}

  

抽象类 C#的更多相关文章

  1. PHP 面向对象编程和设计模式 (1/5) - 抽象类、对象接口、instanceof 和契约式编程

    PHP高级程序设计 学习笔记 2014.06.09 什么是面向对象编程 面向对象编程(Object Oriented Programming,OOP)是一种计算机编程架构.OOP 的一条基本原则是计算 ...

  2. 从接口、抽象类到工厂模式再到JVM来总结一些问题

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习! 涉及到的知识点总结如下: 为什么使用接口? 接口和抽象类的区别 简单工厂模式总结 Java中new和newInstance的区别 J ...

  3. 抽象类 VS 接口

    引言 接口和抽象类是面向对象编程(OOP, Object Oriented programming)中两个绕不开的概念,二者相似而又有所不同.接下来,我们来了解二者的概念并比较它们的异同. 什么是抽象 ...

  4. java抽象类和接口

    面向对象设计过程中重要的一点是如何进行抽象,即把"问题空间"中的元素与"方案空间"中的元素建立理想的一对一的映射关系.抽象类和接口便是抽象过程中的产物.     ...

  5. Java之继承、抽象类、接口篇

    一.继承(extends) 什么是继承? 继承是对现实生活中的"分类"概念的一种模拟. 狮子拥有动物的一切基本特性,但同时又拥有自己的独特的特性,这就是"继承" ...

  6. php中抽象类与接口的概念以及区别

    php里面的接口类,抽象类到底有什么用呢? 刚接触php的时候,觉得这个东西没什么用,其实这些东西还是有一定的作用的,下面我就简单的说说. 1.php 接口类:interface 其实他们的作用很简单 ...

  7. java基础1.-------抽象类,抽象方法

    抽象类:抽象类不能实例化,类中的方法必须经过子类的重写实现 类里的方法是public修饰时,子类可重写也可不重写 类的方法是abstract修饰时,方法是抽象方法,子类必须重写该方法 类的方法用fin ...

  8. java 中抽象类和接口的五点区别?

    1.一个类可以实现多个接口 ,但却只能继承最多一个抽象类. 2.抽象类可以包含具体的方法 , 接口的所有方法都是抽象的. 3.抽象类可以声明和使用字段 ,接口则不能,但接口可以创建静态的final常量 ...

  9. (转)深入理解Java的接口和抽象类

    原文地址: http://www.cnblogs.com/dolphin0520/p/3811437.html 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP ...

  10. Java中接口和抽象类的区别

    经常看到这样的问题,就是问这两个的区别,我这也总结一下: 1,宏观上说,一个是类,一个是接口,类只支持单一继承,接口支持多个继承 2,微观上说,就是从内部来说 a,成员变量方面 接口可以包含方法,属性 ...

随机推荐

  1. python学习笔记:第20天 多继承、MRO C3算法

    目录 一.多继承 二.旧式类的MRO 三.新式类的MRO 四.super 一.多继承 之前已经学习过了继承,当出现了x是⼀种y的的时候,就可以使⽤继承关系,即"is-a" 关系.在 ...

  2. 关于指针的笔记【1】【C语言程序设计-谭浩强】

    指针是什么? 一个 变量的地址称为该变量的"指针"[将地址形象化的称为“指针”].(指针是什么百度百科) 注意区分储存单元的地址和内容这两个概念的区别. 直接访问:直接按变量名进行 ...

  3. 令人懊恼的阉割版fabric sdk功能缺失

    按理说,fabric本身都是用golang开发的,那么fabric-sdk-go作为其亲儿子,功能应该是最为完善的.然而,与我们想法相左的是,golang版本的sdk反而是最不完备的,开发进度滞后,功 ...

  4. [Real World Haskell翻译]第21章 使用数据库

    第21章 使用数据库 从网络论坛到播客采集软件甚至备份程序的一切频繁地使用持久存储的数据库.基于SQL的数据库往往是相当方便:速度快,可扩展从微小到巨大的尺寸,可以在网络上运行,经常帮助处理锁定和事务 ...

  5. 北京Uber优步司机奖励政策(3月16日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. UItraIso 制作ubentu 系统失败

    设备忙,请退出所有正在运行的应用程序,按确定按钮重试. 解决方法: 不要使用UItraIso,不知道为什么一直不行.重启了电脑几次都不行.用Rufus吧 https://rufus.ie/ 注意: r ...

  7. thinkphp5

    分页: thinkphp5分页默认只带page参数 在使用form表单method='get'传递关键字来筛选: 保证每次刷新依旧带上筛选参数 但遇到分页时,下面的分页默认自带page,没有之前筛选的 ...

  8. JDK1.8改为JDK1.7过程

    电脑之前eclipse版本要求JDK1.8版本,现在要用jboss7.1做性能测试,目前仅支持JDK7.故需要降级. 网上有很多说把1.8删掉,这种做法我是不建议的,那么要用的时候呢?又得装回来多蛋疼 ...

  9. Linux命令应用大词典-第31章 设备管理

    31.1 udevadm info:查询udev数据库中的设备信息 31.2 mkdnod:创建块设备和字符设备文件 31.3 MAKEDEV:创建/dev中的设备 31.4 lsblk:列出块设备信 ...

  10. .NET中发送邮件的实现

    .NET中发送邮件 注意: 1.引用下列命名空间: using System.Net; using System.Net.Mail; 2.确保你使用的发送邮件的邮箱开启了stamp服务等. /// & ...