`
Flory
  • 浏览: 23521 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

探讨继承与实现

 
阅读更多

继承是建立一个类,然后创建它的更特殊的版本。是OOP中不可缺少的部分。
人在描述事物的时候是有层次的,那么继承就使程序对现实世界有层次的描述的表达成为可能。对程序员来说继承的重点是共同点。因为有共同点才能重用。

实现是建立一个接口,然后由某些类来实现接口描述的细节。就好比是工程师绘制了部件,然后由工人做出具体的产品,工程师并没有去制造部件。

类与接口的区别就在于此,类不但有描绘,还实现了部分细节。而特殊的抽象类完全带抽象方法,就和接口完成的同样功用。而且,无论接口还是类,都不是凭空去描绘出来的 ,否则就是纸上谈兵了,而是根据具体类的特征抽象出来的。所以他们有共同点。

目录
一、继承与实现
接口实现示例
类继承示例
二、继承,实现简单论述
1、接口的实现以及接口对类的访问
2、类的继承关于以及父类对子类的访问

一、继承与实现
抽象有两种抽象方式。
1、他们有相同的工作方式;
2、他们有相同的名称、作用和特征。
第一种方式是类的继承,而第二种方式是接口的实现。

比如:数据库操作中一般都会用到 添加,删除,更新,读取。那么就是他们都有相同的名称、作用和特征。就可以使用接口实现。

using System.Collections;
using System.Data;

interface IMyData
{
void MyInsert(ArrayList al);
void MyDelete(ArrayList al);
void MyUpdate(ArrayList al);
DataSet MySelect(ArrayList al);
}
using System;

namespace FmRadio
{
/**//// <summary>
/// DMusicSort 的摘要说明。
/// </summary>
public class DMusicSort : IMyData
{
public DMusicSort()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
IMyData 成员#region IMyData 成员

public void MyInsert(System.Collections.ArrayList al)
{
// TODO: 添加 DMusicSort.MyInsert 实现
}

public void MyDelete(System.Collections.ArrayList al)
{
// TODO: 添加 DMusicSort.MyDelete 实现
}

public void MyUpdate(System.Collections.ArrayList al)
{
// TODO: 添加 DMusicSort.MyUpdate 实现
}

public System.Data.DataSet MySelect(System.Collections.ArrayList al)
{
// TODO: 添加 DMusicSort.MySelect 实现
return null;
}

#endregion
}
}
再比如:数据库的连接,这里只说MS Sql Srever 2000,在一个程序只使用一个库的情况下,所有关于数据库操作类都将执行相同的数据库连接。他们有相同的工作方式。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace FmRadio
{
/**//// <summary>
/// MyConnection 的摘要说明。
/// </summary>
public class MyConnection
{
private SqlConnection pConn;

public MyConnection()
{
//
// TODO: 在此处添加构造函数逻辑
//
pConn = new SqlConnection(ConfigurationSettings.AppSettings["DbLink"]);
}

public SqlConnection conn
{
get
{
// TODO: 添加 MyConnection.conn getter 实现
return pConn;
}
}
}
}
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;

namespace FmRadio
{
/**//// <summary>
/// Execute 的摘要说明。
/// </summary>
public class Execute : MyConnection
{
private int sType = 0;
private ArrayList pPara;
private string pContext;

public Execute()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

public Execute(string pContext,ArrayList pPara)
{
this.pPara = pPara;
this.pContext = pContext;
}

public Execute(int pType,string pContext,ArrayList pPara)
{
this.sType = pType;
this.pPara = pPara;
this.pContext = pContext;
}

public int ExeNone()
{
// TODO: 添加 Execute.ExeNone 实现
SqlCommand sc = null;
CommandType ct = CommandType.StoredProcedure;
if(this.sType==0)
ct = CommandType.StoredProcedure;
else
ct = CommandType.Text;

int rs = 0;
sc = new SqlCommand();
sc.CommandType = ct;
sc.Connection = conn;
sc.CommandText = pContext;
foreach(DataPara dp in pPara)
{
sc.Parameters.Add("@" + dp.ColName,dp.ColContent.GetType()).Value = dp.ColContent;
}
// try
// {
conn.Open();
rs = sc.ExecuteNonQuery();
conn.Close();
// }
// catch{}
return rs;
}

public DataSet ExeTable()
{
// TODO: 添加 Execute.ExeTable 实现
SqlDataAdapter sda = new SqlDataAdapter();
SqlCommand sc = null;
CommandType ct = CommandType.StoredProcedure;
if(this.sType==0)
ct = CommandType.StoredProcedure;
else
ct = CommandType.Text;

sc = new SqlCommand();
sc.CommandType = ct;
sc.Connection = conn;
sc.CommandText = pContext;
foreach(DataPara dp in pPara)
{
sc.Parameters.Add("@" + dp.ColName,dp.ColContent.GetType()).Value = dp.ColContent;

}
sda.SelectCommand = sc;
DataSet ds = new DataSet();
// try
// {
conn.Open();
sda.Fill(ds,"asdasd");
conn.Close();
// }
// catch{}
return ds;
}

}
}

二、继承,实现简单论述
下面,我们找更加简单的例子来探讨继承和实现。

1、接口的实现以及接口对类的访问
interface A
{
void a();
}
using System;

namespace Mocl
{
/**//// <summary>
/// A的摘要说明。
/// </summary>
public class A : IA
{
public A()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
IA 成员#region IA 成员

public void a()
{
// TODO: 添加 A.a 实现
System.Diagnostics.Debug.WriteLine("a");
}

#endregion

public void b()
{
System.Diagnostics.Debug.WriteLine("b");
}
}
}
执行以下方法
using System;

namespace Mocl
{
/**//// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/**//// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序

A a = new A();
a.a();
a.b();
IA c = new A();
c.a();
}
}
}


输出
a
b
a

IA c = new A();通过接口访问类。注意使用IA c = new A();的时候,对象c是访问不到类A的方法成员void b()的。因为父类访问子类的时候只会返回父类所定义的方法成员的引用。

我们可以再给类A 添加个字段 public int i = 0;
A的方法a换成
public void a()
{
// TODO: 添加 A.a 实现
System.Diagnostics.Debug.WriteLine("a" + i.ToString());
}

继续执行,发现输出
a0
b
a0
从这点上看出接口对子类的引用并不阻止类执行在访问过程中要使用到的成员,无论这些成员是否是接口的一部分。

2、类的继承关于以及父类对子类的访问
我是在网上看了类似的问题,才有兴趣对继承的各种关系进行学习。才有此文,和大家分享我的学习体会。所以这里就用他的原问题,进行探讨。



public class A
{
public void printA()
{
System.Diagnostics.Debug.WriteLine("printA");
}
public virtual void valueA()
{
System.Diagnostics.Debug.WriteLine("ValueA");
}
}

public class B:A
{
new public void printA()
{
System.Diagnostics.Debug.WriteLine("printB");
}

public override void valueA()
{
System.Diagnostics.Debug.WriteLine("ValueB()");
}
}

using System;

namespace Mocl
{
/**//// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/**//// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
B BTemp=new B();
A ATemp=BTemp;
ATemp.printA();
ATemp.valueA();
BTemp.printA();
BTemp.valueA();
}
}
}

输出:
printA
ValueB()
printB
ValueB()

直接对B的访问B BTemp=new B(); 肯定都能理解。但是A对B的访问 A ATemp=BTemp; (与 A ATemp= new B(); 相当)为什么会得到这样的输出呢?

在讨论问题之前,先来看两个关键字virtual 和new
1、new 的意义
new是在程序编译过程中指定方法引用新的指向地址。
2、virtual 的意义
virtual是在程序运行时确定方法引用的地址。

问题1:类B的方法
new public void printA()
{
System.Diagnostics.Debug.WriteLine("printB");
}
不是覆盖了类A的
public void printA()
{
System.Diagnostics.Debug.WriteLine("printA");
}
了吗?怎么还会输出printA呢?

那是因为new方法只在本类被实例化时才会覆盖父类的方法,它并不直接覆盖父类的方法。
而A ATemp= new B(); 由于类A在编译的时候已经确定了它的结构,除了标明virtual 的成员都已经被固定,而virtual 成员的引用地址是动态执行的。程序运行时,在父类访问子类的时候,需要把子类转换成父类,而子类对virtual 的覆盖将告诉父类的virtual 成员引用的实际地址。new 关键字是不起作用的。new是在编译的时候确定的新引用地址,不会对父类产生影响。

问题2:类B的
public override void valueA()
{
System.Diagnostics.Debug.WriteLine("ValueB()");
}
方法为什么覆盖了父类的
public virtual void valueA()
{
System.Diagnostics.Debug.WriteLine("ValueA");
}
方法。

答案就是上面的
程序运行时,在父类访问子类的时候,需要把子类转换成父类,而子类对virtual 的覆盖将告诉父类的virtual 成员引用的实际地址。

分享到:
评论

相关推荐

    RTTI使用探讨与编码实现

    在C++中如果使用多态继承类,对于多态性的对象,在程序编译时可能会出现无法确定对象的类型的情况,这事就需要通过RTTI动态识别对象的类型。因此,本文探讨了RTTI的使用细节。同时,由于有些平台C++编译器(如...

    Javascript 继承实现例子

    在真正的Web站点和应用程序中,几乎不可能创建名为ClassA和ClassB的类,更可能的是创建表示特定事物(如形状)的类。考虑本章开头所述的形状的例子,Polygon、Triangle和Rectangle类就构成了一组很好的探讨数据。

    JS继承与闭包及JS实现继承的三种方式

    在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 、 成员属性、静态属性、原型属性与JS原型链)。今天我们来继续探讨剩余的内容吧。 我们都知道,面向对象的三大...

    C#中的继承和多态构建一个定义明确的类类型

    研究了oop的第一个支柱封装,探讨了如何使用继承来构建一族相关类

    基于J2EE架构下网络教学平台的设计与实现

    性、具备开放性与继承性。J2EE是一个涉及多个层 面的复杂概念,系统采用Browser/Web Server、Appli2 cation Server和DB Server多层结构,方便系统的维护 和扩充系统完全,提供比Windows更安全的、更能扩 展的应用服务器...

    C++菱形继承原理分析

    为了探讨菱形虚拟继承如何解决该问题,我先建立个一个较为简单的菱形继承模型。下面分别是菱形继承和菱形虚拟继承的代码实现: //菱形继承 #include #include using namespace std; class AA { public: int ...

    OOP中继承机制剖析

    进行对比分析,探讨了C++语言中由继承带来的属性的隐藏和方法的覆盖、遮蔽等重要性质,得出使用继承不仅可以使得大量的代码可以复用,而且可以大大减少代码和数据的冗余度,同时由方法的覆盖可以实现真正意义上的...

    网络数据库安全设计与实现.doc

    为此,本文主要探讨了网络数据库的安全设计及实现,为网络 数据库使用客户提供技术保障。 2.相关技术 2.1 基于角色的访问控制RBAC RBAC的原理描述如下:用户对应的访问权限是经过授权而获得的,权限只能与角色相 ...

    通过反汇编理解 C++语言实质探讨

    比如对象模型的构造、存储、数据与成员函数之间的联系,以及多态、继承、封装等,对其实质性技术觉得既抽象又具迷惑性。以 致在使用中连连碰壁,结果是不得已而求其次,纷纷转入使用其它可视化编程工具。 本文从...

    C++继承中的访问控制实例分析

    本文较为深入的探讨了C++继承中的访问控制,对深入掌握C++面向对象程序设计是非常必要的。具体内容如下: 通常来说,我们认为一个类有两种不同的用户:普通用户 和 类的实现者。其中,普通用户编写的代码使用类的...

    在JavaScript中实现类的方式探讨

    在 javascript 中有很多方式来创建对象,所以创建对象的方式使用起来非常灵活。那么,到底哪一种方式是最恰当的对象创建方式呢?...它没有类继承机制,但是可以通过原型(prototype)实现继承。 现在看起来,

    征服Python全栈面试:掌握这20个问题,助你脱颖而出!.zip

    内容关键词:面试题、答案、列表与元组、异常处理、全局变量、局部变量、MVC、Git与GitHub区别、继承实现、生成器与迭代器、多线程实现、RESTful API定义、拷贝实现、装饰器链、事务管理、单元测试、闭包概念、...

    电信软交换网络向IMS平滑演进的探讨

    IMS目前在业界备受关注,公认是固网和移动网演进的一个重要环节,是未来网络融合的焦点,是实现FMC的最佳途径。软交换和IMS是固网向NGN演进的不同阶段。IMS不仅继承了软交换的技术特点,如控制和承载相分离、业务和...

    NGN业务建设思路探讨

    NGN网络下的业务部署一定要在充分继承原有业务的基础上,发挥核心网络统一IP承载、无处不在的多媒体、天然的多方控制等优势,拓展融合的、多媒体的用户体验,探索开放的、可运营、可管理的盈利模式,实现产业链的...

    毕业设计:C#网络办公助理设计与实现(源代码)

     当同一办公室的两位员工有问题探讨时,还得离开自己的位置交谈,这就会对其他人员造成影响。  当有资源共享时,只是简单的共享,有着很大的安全隐患。有些甚至还在使用纸介质。 当要召开会议时。既需要专人...

    C/C++杂记 虚函数的实现的基本原理(图文)

    简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针。例: 其中: B的虚函数表中存放着B::foo和B::bar两个函数指针。 D...

    ASP.NET开发实战1200例(第Ⅰ卷)第三章

    3.1 面向对象家族核心——类与类成员 112 实例073 面向对象编程核心——类、对象和 引用 112 实例074 绘制家谱——用ASP.NET创建类 文件 114 实例075 定制家族权力——设置成员访问的 权限 116 实例076 展现家族...

    Visual C++实践与提高-COM和COM+篇『PDF』

    6.5.2 模板和多继承 6.5.3 几个重要的类 6.5.3.1 CComModule 6.5.3.2 CComObjectRoot/CComObjectRootEx 6.5.3.3 CComCoClass 6.5.3.4 CComObject 6.6 使用ATL开发COM组件——例程ATLSample 6.6.1 创建一个新的ATL...

    探讨javascript是不是面向对象的语言

    他没有类(在javascript2.0真正实现之前),但它却有构造器可以做类能做的事,包括扮演变量和方法的容器和角色。他没有基于类的继承,但它有基于原型的继承。两个建立对象系统的方法是通过继承和通过聚合。...

    涡扇发动机实现变循环功能的循环参数设计 (2014年)

    探讨了基于约束条件的涡扇发动机实现变循环功能循环参数分析方法,并研究了可调部件/机构对变循环发动机总体性能的影响。研究表明,通过基于涡扇发动机实现变循环功能循环参数分析可确定原准机的改装方案,且继承自...

Global site tag (gtag.js) - Google Analytics