.NET接口和抽象类(转载)

本文详细解释了接口和抽象类的概念及其区别,包括定义方法、使用场合及编程原则,为面向对象编程提供了实用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

  •        什么是接口?

接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现,CLR 允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。但是注意:C# 中不能包含任何静态成员。一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法。

定义方法为:

public interface System.IComparable
  {
        int CompareTo(object o);
    }

    public class TestCls: IComparable
    {
        public TestCls()
        {
        }

        private int _value;
        public int Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public int CompareTo(object o)
        {

            //使用as模式进行转型判断
            TestCls aCls = o as TestCls;
            if (aCls != null)
            {

            //实现抽象方法
            return _value.CompareTo(aCls._value);
            }
        }
    }

  •         什么是抽象类?

抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。抽象类不能实例化,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new 关键字,也不能被密封。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由overriding 方法来实现。

定义方法为:

/// <summary>
/// 定义抽象类
/// </summary>
abstract public class Animal
{
    //定义静态字段
    protected int _id;

    //定义属性
    public abstract int Id
    {
        get;
        set;
    }

    //定义方法
    public abstract void Eat();

    //定义索引器
    public string this[int i]
    {
        get;
        set;
    }
}

/// <summary>
/// 实现抽象类
/// </summary>
public class Dog: Animal
{
    public override int Id
    {
        get {return _id;}
        set {_id = value;}
    }

    public override void Eat()
    {
        Console.Write("Dog Eats.")
    }
}

 

相同点

  • 都不能被直接实例化,都可以通过继承实现其抽象方法。
  • 都是面向抽象编程的技术基础,实现了诸多的设计模式。

 

不同点

  • 接口支持多继承;抽象类不能实现多继承。
  • 接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。
  • 接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。
  • 接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。
  • 接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。 
  • 接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct 就可以继承接口,而不能继承类。

 规则与场合

  • 请记住,面向对象思想的一个最重要的原则就是:面向接口编程。
  • 借助接口和抽象类,23 个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程。
  • 抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
  • 接口着重于CAN-DO 关系类型,而抽象类则偏重于IS-A 式的关系;
  • 接口多定义对象的行为;抽象类多定义对象的属性; 
  • 接口定义可以使用public 、protected 、internal  和private 修饰符,但是几乎所有的接口都定义为public ,原因就不必多说了。
  •  “ 接口不变” ,是应该考虑的重要因素。所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。
  • 尽量将接口设计成功能单一的功能块,以.NET Framework 为例,IDisposable 、IDisposable 、IComparable 、IEquatable 、IEnumerable 等都只包含一个公共方法。
  • 接口名称前面的大写字母“I” 是一个约定,正如字段名以下划线开头一样,请坚持这些原则。
  • 在接口中,所有的方法都默认为public 。 
  • 如果预计会出现版本问题,可以创建“ 抽象类” 。例如,创建了狗(Dog )、鸡(Chicken )和鸭(Duck ),那么应该考虑抽象出动物(Animal )来应对以后可能出现风马牛的事情。而向接口中添加新成员则会强制要求修改所有派生类,并重新编译,所以版本式的问题最好以抽象类来实现。
  • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
  • 对抽象类不能使用new 关键字,也不能被密封,原因是抽象类不能被实例化。
  • 在抽象方法声明中不能使用 static 或 virtual 修饰符。

 

绝对经典

.NET Framework 是学习的最好资源,有意识的研究FCL 是每个.NET 程序员的必修课,关于接口和抽象类在FCL 中的使用,我有以下的建议:

  • FCL 对集合类使用了基于接口的设计,所以请关注System.Collections 中关于接口的设计实现;
  • FCL 对数据流相关类使用了基于抽象类的设计,所以请关注System.IO.Stream 类的抽象类设计机制。

 

 

 

转载于:https://www.cnblogs.com/michaelShao/archive/2010/05/26/1744621.html

在 Java 的学习与开发过程中,总有一些概念容易让人混淆,从而在编程时出现各种问题。今天,我们就来深入剖析几对极易混淆的概念,通过代码示例与图示,帮助大家彻底理清它们之间的区别与联系。 目录 一、线程与进程 1.1 概念 1.2 区别 1.3 代码示例 二、值传递与引用传递 2.1 概念 2.2 区别 三、接口抽象类 3.1 概念 3.2 区别 3.3 代码示例 总结 一、线程与进程 1.1 概念 进程:是计算机中已运行的程序的实体,是系统进行资源分配调度的基本单位。每个进程都有自己独立的内存空间、系统资源等,进程之间相互隔离,安全性高。例如,当我们同时打开浏览器、音乐播放器文档编辑器时,它们分别对应一个进程,彼此互不干扰。 线程:是进程中的一个执行单元,是程序执行的最小单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件句柄等。线程之间的切换通信开销相对较小,能提高程序的执行效率。 1.2 区别 我们可以通过一张表格直观地看出线程与进程的区别: 对比项 进程 线程 资源分配 独立分配资源,有独立内存空间 共享进程资源 执行开销 创建、撤销、切换开销大 创建、撤销、切换开销小 并发性能 进程间并发,开销大 线程间并发,开销小 安全性 进程间相互隔离,安全性高 共享资源,需考虑同步问题 1.3 代码示例 下面是一个简单的 Java 多线程示例,通过创建线程类并启动线程,展示线程的使用: class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " 正在执行:" + i); } } } public class ThreadAndProcess { public static void main(String[] args) { MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); thread1.start(); thread2.start(); } } AI写代码 java 运行 在上述代码中,我们创建了MyThread类继承自Thread类,重写run方法定义线程执行的逻辑。在main方法中创建两个线程对象并启动,此时两个线程会并发执行run方法中的代码。 二、值传递与引用传递 2.1 概念 值传递:是指在方法调用时,实际参数将其值复制一份传递给形式参数,在方法内部对形式参数的修改不会影响到实际参数的值。简单来说,就是传递的是数据的副本。 引用传递:在方法调用时,实际参数将其引用(内存地址)传递给形式参数,形式参数实际参数指向同一内存地址,在方法内部对形式参数的修改会直接影响到实际参数。 2.2 区别 在 Java 中,只有值传递。对于基本数据类型,传递的是值本身;对于引用数据类型,传递的是对象的引用(地址值)。虽然看起来像是引用传递,但本质上还是值传递,因为传递的是引用的副本。我们通过代码来验证: public class PassByValue { public static void changeInt(int num) { num = 100; } public static void changeArray(int[] arr) { arr[0] = 100; } public static void main(String[] args) { int num = 10; changeInt(num); System.out.println("修改后的num:" + num); int[] arr = {10}; changeArray(arr); System.out.println("修改后的arr[0]:" + arr[0]); } } AI写代码 java 运行 在上述代码中,changeInt方法接收一个基本数据类型int的参数,在方法内部修改参数值后,不会影响到main方法中num的值。而changeArray方法接收一个引用数据类型int[]的参数,在方法内部修改数组元素的值,会影响到main方法中arr数组对应元素的值。这是因为传递的是数组的引用副本,通过该引用副本依然可以访问修改原数组。 三、接口抽象类 3.1 概念 抽象类:使用abstract关键字修饰的类,抽象类中可以包含抽象方法(只有方法声明,没有方法体)非抽象方法。抽象类不能被实例化,只能被继承,子类必须实现抽象类中的抽象方法(除非子类也是抽象类)。抽象类通常用于抽取相关类的共性,作为父类来定义一些通用的行为属性。 接口:使用interface关键字定义,接口中的方法默认是public abstract的(可以省略不写),属性默认是public static final的常量。接口不能被实例化,类通过implements关键字实现接口,一个类可以实现多个接口接口用于定义一种规范,实现接口的类必须实现接口中定义的所有方法。 3.2 区别 同样,我们通过表格来对比接口抽象类: 对比项 抽象类 接口 定义方式 使用abstract class定义 使用interface定义 继承 / 实现 子类通过extends继承抽象类 类通过implements实现接口 方法 可以包含抽象方法非抽象方法 只能包含抽象方法(JDK 8 后可添加默认方法静态方法) 属性 可以包含各种类型的属性 只能包含public static final常量 多继承 一个类只能继承一个抽象类 一个类可以实现多个接口 3.3 代码示例 先看抽象类的示例: abstract class Animal { protected String name; public Animal(String name) { this.name = name; } public abstract void speak(); } class Dog extends Animal { public Dog(String name) { super(name); } @Override public void speak() { System.out.println(name + " 汪汪叫"); } } AI写代码 java 运行 在上述代码中,Animal是抽象类,包含一个抽象方法speak。Dog类继承自Animal类,并实现了speak方法。 再看接口的示例: interface Flyable { void fly(); } class Bird implements Flyable { @Override public void fly() { System.out.println("鸟儿在飞翔"); } } AI写代码 java 运行 总结 这里定义了Flyable接口,包含fly抽象方法,Bird类实现了Flyable接口并实现了fly方法。 通过以上对线程与进程、值传递与引用传递、接口抽象类的深入剖析对比,我们可以更清晰地理解它们之间的区别与联系。 在学习 Java 编程过程中,理解这些基础概念至关重要。线程与进程是操作系统中的重要概念,而值传递与引用传递则涉及到方法调用时参数传递的机制,对于理解 Java 中的数据传递有着重要意义。同时,接口抽象类是面向对象编程中的重要组成部分,能够帮助我们更好地设计组织代码。 通过深入研究这些概念,结合代码示例区别对比,我们可以更好地掌握 Java 编程中的关键知识点,避免混淆错误的应用,提高编程效率质量。希望以上内容能够帮助您更好地理解运用这些概念,在 Java 学习与开发中取得更好的成果。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接本声明。 原文链接:https://blog.csdn.net/2401_88952086/article/details/148977946补充说明
最新发布
06-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值