【C#基础】C# 面向对象编程

这篇具有很好参考价值的文章主要介绍了【C#基础】C# 面向对象编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

序号 系列文章
5 【C#基础】C# 运算符总结
6 【C#基础】C# 常用语句讲解
7 【C#基础】C# 常用数据结构

前言

😊大家好,我是writer桑,前面一章已经学习了 C# 中的常用数据结构,那本章就开始学习 C# 程序中面向对象编程的知识,希望看完大家能够有所收获,感谢支持!


面向对象的 C#

面向对象编程是一种计算机编程架构(Object Oriented Programming,简称OOP)。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。OOP的三大特征分别为封装、继承和多态。用公式概括为:OOP=对象+类+继承+多态+消息,其中核心概念是类和对象。 C# 就是一种面向对象的编程语言,完美实现了抽象、封装、继承和多态性的面向对象特性。

1,类的概念

类的创建就相当于生成了一个蓝图。在蓝图中指定该类可以进行哪些操作,也就是在类中创建指定字段、属性和方法成员。对象是类的实例,类对象的组成和操作都是由类决定的。 在 C# 程序中使用"访问修饰符"(可选)+ class 关键字 + "类的名称"来声明类。

示例如下:

public class Person		// 类名称的声明
{
    public string Name { get; set; }	// 成员属性 
    public int Age { get; set; }
    
    // 成员函数 
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    // 成员方法 
    public void MethodBody()
    {
        Console.WriteLine("Hello,World");
    }
    
    // 其他属性、方法、事件…… 
}

2,类的定义

C# 定义类使用唯一的标识符 class 。 类定义的语法可概括为 <access specifier> class class_name , 其中 <access specifier> 为访问修饰符,class_name 为类的名称,类名称必须符合 C# 的命名规范。

访问修饰符的概念和使用:

class 关键字前面前面是访问修饰符,示例中使用的是 public 修饰符 ,也可以是 public、private、protected、internal、protected internal 和 private protected,默认为 internal 。 这些访问修饰符分别表达的意思以一个表格来展示。

表格如下:

访问修饰符 描述
public 同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。 某一类型的公共成员的可访问性水平由该类型本身的可访问性级别控制。
private 只有同一 class 或 struct 中的代码可以访问该类型或成员。
protected 只有同一 class 或者从该 class 派生的 class 中的代码可以访问该类型或成员。
internal 同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。 换句话说,internal 类型或成员可以从属于同一编译的代码中访问。
protected internal 该类型或成员可由对其进行声明的程序集或另一程序集中的派生 class 中的任何代码访问。
private protected 该类型或成员可以通过从 class 派生的类型访问,这些类型在其包含程序集中进行声明。

抽象类的概念和使用:

使用 abstract 关键字可以创建不完整且必须在派生类中实现的类和 class 成员,称为抽象方法。 C# 规定抽象方法的实现必须放在抽象类中。抽象类不能实例化,抽象类的用途就是提供一个可供多个派生类共享的通用基类定义。通过在类定义前面放置 abstract 修饰符将其声明为抽象类。

示例如下:

using System;

public abstract class AbstProgram            // 必须声明为抽象类 
{
    public abstract string abstMethod();     // 抽象方法

}

public class Subclass : AbstProgram
{
    // 抽象方法必须实现
    public override string abstMethod()
    {
        return "hello,abstMethod";
    }
}

密封类的概念和使用:

使用 sealed 修饰符应用于某个类时,这个类称为密封类。密封类可以阻止其他类继承自该类,还可以对替代基类中的虚方法或属性的方法或属性使用 sealed 修饰符。这使得类派生自你的类并防止它们替代特定虚方法或属性。

示例如下:

using System; 

public class Program
{
    public virtual void virmethod()          // 虚方法 
    {
        Console.WriteLine("hello,virmethod");
    }
}

public sealed class SealClass : Program      // 密封类 
{
    public override sealed void virmethod()
    {
        Console.WriteLine("hello, sealed");
    }
}

静态类的概念和使用:

类的声明可以添加 static 修饰符声明为静态类。 静态类只能包含静态成员,不能使用 new 关键字字进行实例化。 静态类基本上与非静态类相同,但有一个区别就是静态类无法被实例化。由于不存在任何实例变量,因此可以使用类名本身访问静态类的成员。

示例如下:

using System;

// 静态类 
static class StaticMethod
{
    public static int number = 4;
 
    public static int getNumber()
    {
        return number; 
    }
}; 

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(StaticMethod.getNumber()); 
    }
}

3,类成员

类的成员包括在类中声明的所有成员, 以及在该类中的继承层次结构中的所有类中声明的所有成员(构造函数和析构函数除外)。 注意基类中的私有成员被继承,但是不能从派生类中访问。 在类中定义的字段、属性、方法和事件都可以称为类成员。

字段和属性的概念与使用:

字段也就是在类范围声明的变量,字段可以是内置数值类型或其他类的实例。 属性是类中可以像类中的字段一样访问的方法。属性可以为类字段提供保护,以避免字段在对象不知道的情况下被更改。

示例如下:

using System; 

public class Person
{
    public int age;     // 字段的声明 

    // 属性的声明 
    public int Age
    {
        set
        {
            if(value > 0 && value < 100)
            {
                age = value;
            }
        }
        get 
        {
            return age;
        }
    }
}

字段和属性的区别:

  • 属性相当于在类中的变量,而字段具备 set 和 get 的操作。
  • 读取字段的值时,程序走的是 get{} 操作;给字段赋值时,程序走的是 get{} 操作。
  • 当想让字段不被赋值时,可以只写get{} 操作,不写 set{} 操作。

构造函数和析构函数的概念与使用:

构造函数是一个特殊的成员函数,是在首次创建类对象时执行的方法,它们通常用于初始化对象的数据。构造函数的名称和类的名称完全相同,且没有任何返回类型。 折构函数也是类的一个特殊的成员函数, 是在类的对象超出范围时执行,通常用于结束程序(比如关闭文件、释放内存等)之前释放资源。折构函数在类名称前面加一个 ~ 前缀进行声明,而且不具备任何返回值和参数。

示例如下:

using System; 

public class Person
{
    private string last;
    private string first;

    // 构造函数的声明并且初始化类字段
    public Person(string lastName, string firstName)
    {
        last = lastName;
        first = firstName;
    }
} 
using System;

class Person
{
    private int age;

    // 构造函数 
    public Person()  
    {
        Console.WriteLine("对象已创建");
    }

    //析构函数
    ~Person() 
    {
        Console.WriteLine("对象已删除");
    }
}

类方法的概念和使用:

方法是包含一系列语句的代码块,类方法定义类可以执行的操作。程序通过调用该方法并指定任何所需的方法参数使语句得以执行。方法可接收提供输入数据的参数,并可通过参数返回输出数据。方法也可以不使用参数而直接返回值。 使用 “访问修饰符” + “返回数据类型” + “方法名称” 的格式来声明类方法。

示例如下:

public class Person
{
    // 成员方法 
    public void MethodBody()
    {
        Console.WriteLine("Hello,World");   // "Hello,World"
    }
}

虚方法的概念和使用:

虚方法也就是可以被派生类重写的方法,如果派生类重写基类中的虚方法,则在运行时将运行重写的行为。但是如果派生类没有重写虚方法,则运行时执行基类中的虚方法行为。 在 C## 程序中,使用 virtual 关键字来声明虚方法。

示例如下:

public class Rectangular
{
    // 虚方法
    public virtual double Area(int x, int y)
    {
        return x * y;
    } 
}

public class Program : Rectangular
{
    // 重写虚方法 
    public override double Area(int x, int y)
    {
        return x * y;
    }
}

抽象方法的概念和使用:

抽象方法也是可以被派生类重写的方法,但是和虚方法不同的是抽象方法是强制派生类重写的方法, 否则派生类就不能实例化。 抽象方法只能在抽象类中声明,可以使用 abstract 修饰符进行声明。 抽象方法只有方法名称, 没有方法实现。

示例如下:

public abstract class Animal
{
    // 抽象方法的声明 
    public abstract void Sleep();
    public abstract void Eat();
}


public class Person : Animal
{
    // 必须实现基类中的抽象方法
    public override void Eat()
    {
        throw new NotImplementedException();
    }

    public override void Sleep()
    {
        throw new NotImplementedException();
    }
}

点击了解虚方法和抽象方法的异同,整理第一条。

4,对象

对于面向对象的编程语言,一切皆为对象,对象是程序的基本单元。对象把程序与数据封装起来提供对外访问的能力,提高软件的重用性,灵活性和扩展性。前面说过类或结构定义的作用类似于蓝图 ,指定着该类或结构可以进行哪些操作。 而类的对象是此蓝图分配和配置的内存块。

创建类对象的操作:

C# 程序允许同一个类实例化出多个对象。 可以通过这些对象来操作类中的方法、字段与属性等类成员。可以使用 new 运算符创建类对象,同时指定对象的名称和类型参数。

示例如下:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

class Program
{
    static void Main()
    {
        // 创建对象 person1 
        Person person1 = new Person("Leopold", 6);
        Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
    }
}
/*
    输出:
    person1 Name = Leopold Age = 6
*/

对象的标识与值相等性:

当比较两个对象是否相等时,首先必须明确是想知道两个对象是否是同一个引用,还是这两个对象一个或多个字段的值是否相等。如果是前者,可使用静态 Object.Equals 方法。 如果是后者,可以使用 Equals 方法或 == 运算符。

示例如下:

Person p1 = new Person("Wallace", 75);
Person p2 = p1; 

if (p2.Equals(p1))
    Console.WriteLine("p2和p1有相同的值。");

if (p1.Name == p2.Name)
    Console.WriteLine("p1和p2的Name属性相等。"); 

5,继承

继承是面向对象编程的三大特征之一。通过继承,可以重用、扩展和修改被继承类的行为。其中被继承的类称为"基类",继承这些基类的类称为派生类。 虽然派生类只能有一个直接基类,但是继承之间是可以传递的。 比方说 ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC 将继承在 ClassB 和 ClassA 中声明的成员。

继承的使用:

class 关键字前面的是类的名称。 在示例中类的名称为 Person 。类(而非结构)支持继承的概念。派生自另一个类(称为基类)的类自动包含基类的所有公共、受保护和内部成员(其构造函数和终结器除外)。 在 C# 程序中使用 :标识符来声明要继承的父类。

示例如下:

public class Animal
{
    public static void animalMethod()
    {
        Console.WriteLine("这是Animal类的方法");
    }
}

public class Person : Animal   // 继承父类 Animal
{ 
    static void Main(string[] args)
    {
        animalMethod();     // 这是Animal类的方法
    }
}

多重继承的示例:

using System;

// 这是基类 Shape 
public class Shape
{
    public void setWidth(int w)
    {
        width = w;
    }
    public void setHeight(int h)
    {
        height = h;
    }
    protected int width;
    protected int height;
}

// 这是接口 PaintCost
public interface PaintCost
{
    int getCost(int area);

}

// 派生类继承基类 Shape 和接口 PaintCost
public class Rectangle : Shape, PaintCost
{
    public int getArea()
    {
        return (width * height);
    }

    // 实现接口中的方法 
    public int getCost(int area)
    {
        return area * 70;
    }
}


public class RectangleTester
{
    static void Main(string[] args)
    {
        Rectangle Rect = new Rectangle();
        int area;
        Rect.setWidth(5);
        Rect.setHeight(7);
        area = Rect.getArea();

        // 打印对象的面积
        Console.WriteLine("总面积: {0}", Rect.getArea());
        Console.WriteLine("油漆总成本: ${0}", Rect.getCost(area));
        Console.ReadKey();
    }
}

接口的概念和使用:

类不仅可以继承父类,还可以继承接口。C# 的接口义了所有类或者结构体继承接口时应实现的一组相关功能的定义。 接口中可以定义属性、方法和事件,这些都是接口的成员。但是接口不能声明实例数据,如字段、自动实现的属性或类似属性的事件。接口只包含了成员的声明,而成员的实现是派生类的任务,一个派生类支持继承多个接口,接口也可以继承其它接口。使用 interface 修饰符来声明一个接口。

示例如下:

interface IMyInterface       // 声明接口 IMyInterface 
{
    public void intMethod();    // 接口定义的方法
}

public class Person : IMyInterface	// Person 类继承接口 IMyInterface 
{
    public void intMethod()    // 实现接口的方法
    {
        throw new NotImplementedException();
    }
}

点击了解抽象类和接口的异同,第二条整理。

6,多态性

多态性常被视为自封装和继承之后,面向对象编程的第三个支柱。 多态性表示当同一操作作用于不同的对象时,可以有不同的行为,返回多种执行结果。在实际的应用中,多态性常表现为“一个接口,多个功能。 C# 的多态性可以是静态的或者动态的。 在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。

静态多态性:

编译时的多态性是通过重载实现的, 对于非虚的成员, 系统在编译时会根据传递的参数、返回的类型等信息决定实现何种操作。在编译期间,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性,分别为函数重载运算符重载。 以函数重载为示例,点击了解运算符重载。

示例如下:

using System;

public class TestData
{ 
    // 函数重载 
    public int Add(int a, int b, int c)
    {
        return a + b + c;
    }
    public int Add(int a, int b)
    {
        return a + b;
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestData dataClass = new TestData();
        int add1 = dataClass.Add(1, 2);
        int add2 = dataClass.Add(1, 2, 3);

        Console.WriteLine("add1 :" + add1);
        Console.WriteLine("add2 :" + add2);
    }
}

动态多态性:

除了静态多态性外,还有动态多态性。也即只有到系统运行时,程序才根据实际情况实现具体行为。C# 支持的动态多态性可以通过重写基类中抽象方法和虚方法来实现。

抽象方法的示例:

using System;

abstract class Shape
{
    // 声明抽象方法
    abstract public int area();
}

class Rectangle : Shape
{
    private int length;
    private int width;

    // 声明构造函数 
    public Rectangle(int a = 0, int b = 0)
    {
        length = a;
        width = b;
    }

    // 重写父类的抽象方法 
    public override int area()
    {
        Console.WriteLine("Rectangle 类的面积:");
        return (width * length);
    }
}

class RectangleTester
{
    static void Main(string[] args)
    {
        Rectangle r = new Rectangle(10, 7);
        double a = r.area();
        Console.WriteLine("面积: {0}", a);
        Console.ReadKey();
    }
}

虚方法的示例:

using System;
using System.Collections.Generic;

public class Animal
{
    // 虚方法
    public virtual void Run()
    {
        Console.WriteLine("执行动物跑的行为");
    }
}

class Cat : Animal
{
    // 重写基类Animal中的Run方法 
    public override void Run()
    {
        Console.WriteLine("猫在跑");
        base.Run();
    }
}

class Dog : Animal
{
    public override void Run()
    {
        Console.WriteLine("狗在跑");
        base.Run();
    }
}

class Pig : Animal
{
    public override void Run()
    {
        Console.WriteLine("猪在跑");
        base.Run();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建一个 List<Animal> 对象,并向该对象添加 Cat、Pig 和 Dog
        var shapes = new List<Animal>
        {
            new Dog(),
            new Pig(),
            new Cat()
        };

        // 使用 foreach 循环对该列表的派生类进行循环访问,并对其中的每个 Animal 对象调用 Run 方法
        foreach (var shape in shapes)
        {
            shape.Run();
        }

        Console.WriteLine("按下任意键退出。");
        Console.ReadKey();
    }

}

结语

🌟 以上就是 C# 面向对象编程知识点的介绍,希望能够对大家有所帮助。望大家多多支持,你们的支持就是笔者创作最大的动力!文章来源地址https://www.toymoban.com/news/detail-443416.html

到了这里,关于【C#基础】C# 面向对象编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第七章 面向对象编程(基础)

    (1)类是抽象的,概念的,代表一类事物,比如人类、猫类... 即它是数据类型。 (2)对象是具体的,实际的,代表一个具体事物,即实例。 (3)类是对象的模板,对象是类的一个个体,对应一个实例。 属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对

    2024年02月06日
    浏览(86)
  • 【python】08.面向对象编程基础

    活在当下的程序员应该都听过\\\"面向对象编程\\\"一词,也经常有人问能不能用一句话解释下什么是\\\"面向对象编程\\\",我们先来看看比较正式的说法。 \\\"把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部

    2024年01月20日
    浏览(50)
  • 【java】面向对象的编程基础

    true false 这里输入set和get可以自动将函数补全,传参初始化在构造属性之后 cc ccccc coleak 这里说明先构造属性,再执行代码块,再初始化 静态代码块 4 4 我是静态变量初始化 我是静态代码块 我是成员变量初始化 我是普通代码块 我是构造方法 快速构造,点击生成,构造函数,

    2023年04月16日
    浏览(45)
  • Java基础(七)面向对象编程(高级)

    回顾类中的实例变量(即非static的成员变量) 创建两个Circle对象: Circle类中的变量radius是一个实例变量(instance variable),它属于类的每一个对象,c1中的radius变化不会影响c2的radius,反之亦然。 如果想让一个成员变量被类的所有实例所共享,就用static修饰即可,称为类变量(

    2023年04月16日
    浏览(43)
  • C++ 递归与面向对象编程基础

    递归是一种使函数调用自身的技术。这种技术提供了一种将复杂问题分解为简单问题的方法,从而更容易解决问题。 递归可能有点难以理解。理解其工作原理的最佳方法是通过实验来尝试。 将两个数字相加很容易做到,但将一系列数字相加就更复杂了。在下面的示例中,通

    2024年04月16日
    浏览(38)
  • 7.面向对象编程(基础部分)|Java学习笔记

    java 设计者 引入 类与对象(OOP) ,根本原因就是现有的技术,不能完美的解决新的新的需求. 类是抽象的,概念的,代表一类事物,比如人类,猫类…, 即它是数据类型. 对象是具体的,实际的,代表一个具体事物, 即 是实例. 类是对象的模板,对象是类的一个个体,对应一个实例

    2024年02月08日
    浏览(48)
  • Python基础-11 面向对象编程_各种方法

    python本身支持类的动态属性 直接使用等号=,给一个属性赋值 如果这个属性存在,则会修改该属性的值 如果这个属性不存在,则会给对象添加一个新的属性及对应的值 如果需要禁止动态添加类的属性,可以使用 __slots__ 属性,如下示例 这个属性直接定义在类中,是一个元组,用来规定

    2023年04月17日
    浏览(47)
  • 【Java零基础入门篇】第 ③ 期 - 面向对象编程(一)

    博主:命运之光 专栏:Java零基础入门 理解面向对象三大主要特征; 掌握类与对象的区别与使用; 掌握类中构造方法以及构造方法重载的概念及使用; 掌握包的定义、包的作用等; 掌握方法的参数传递规则。 方法的定义 🍓🍓方法在很多地方被称为 函数 (在Java中英文单

    2024年02月04日
    浏览(55)
  • 【Java零基础入门篇】第 ③ 期 - 面向对象编程(二)

    博主:命运之光 专栏:Java零基础入门 学习目标 理解面向对象三大主要特征; 掌握类与对象的区别与使用; 掌握类中构造方法以及构造方法重载的概念及使用; 掌握包的定义、包的作用等; 掌握方法的参数传递规则。 什么是封装? 本意是把物体打包装到箱子里,然后封起

    2024年02月04日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包