Csharp面向对象

Csharp面向对象

封装(get/set)

与Java不同,C#的get和set写法很特别

并且,我们可以在set和get方法中加以对数据的处理

注:在C#中,我们严格区分了属性和字段的概念

  • 字段:私有的,通常以下划线+小写字母开头
  • 属性:公共的,通常以大写字母开头

通过使用属性,我们可以在不暴露实际字段的情况下,提供对类内部状态的访问

namespace HelloWorld;

class Hello
{
    // 字段name
    private string name;
    
    // 属性Name
    public string Name
    {
        get { return name; }
        // value 就是调用Name时传入的参数
        set { name = value; }
    }

    public static void Main(string[] args)
    {
        Hello hello = new Hello();
        // 调用属性Name中的set方法
        hello.Name = "xiaobai";
        
        //调用属性Name中的get方法
        var rectangleName = hello.Name;
        
        Console.WriteLine(rectangleName);
    }
}

自动实现的属性

C# 还支持自动实现的属性(Auto-Implemented Properties),这是一种简化的属性定义方式,编译器会自动为你创建一个私有字段来支持该属性

注:这个字段由编译器自动生成的一个内部名称。这种方式使得代码更加简洁,并且易于维护

namespace HelloWorld;

class Hello
{
    public string Name { get; set; }

    public static void Main(string[] args)
    {
        Hello hello = new Hello();
        // 调用属性Name中的set方法
        hello.Name = "xiaobai";

        //调用属性Name中的get方法
        var rectangleName = hello.Name;

        Console.WriteLine(rectangleName);
    }
}

属性访问器注意事项
  • get方法不可以被省略

  • set方法可以被省略

    • 构造方法可以对省略set的属性进行赋初值
    • 类中其他方法不可以对省略set的属性进行操作
  • 在set前使用private修饰后,则可以实现只有本类能对属性进行set操作

  • 不能在set和get上同时使用private修饰

  • 属性的访问限定符可以同时对set和get上进行修饰(get和set继承属性的访问修饰符)


继承&实现

在Java中,继承与实现是不同的关键字

在C# 中,继承与实现都是:来实现的

并且在C# 中,也是可以同时实现多个接口的

注:私有成员(方法、属性、事件)是无法被继承和实现的

在Java中,我们调用父类中的属性(方法)时,使用关键字super

而在C#中,使用关键字base调用


显式调用父类构造方法

当父类只有一个带参构造时,需要其子类显式调用其父类构造方法

但如果存在一个带参构造时,基本上都要单独声明一个无参构造方法

public class Father
{
    public String Xing;
    public Father(String xing)
    {
        this.Xing = xing;
    }
}

public class Son : Father
{
    // 显式调用父类的构造方法
    public Son(String xing) : base(xing)
    {
        this.Xing = xing;
    }
}

多态&重写

当子类存在与父类相同名字相同参数的方法时,父类方法并没有被重写覆盖,而是对父类方法进行一个隐藏(与Java不同点)

注:当写同名同参方法时(隐藏父方法而非重写),子方法被C#推荐要加上new关键字

可以通过base关键字调用到被隐藏的父类方法

  • virtual关键字,用以修饰父类方法,将其标记成虚拟方法

  • override重写关键字,用以重写父类方法

使用这一对关键字,就可以构成方法的重写

而C#同时存在abstract关键字,用以修饰父类方法,将其标记成抽象方法

abstractvirtual的明显区别是,abstract强制要求其子类重写此方法,而virtual不强制重写

注:当父类方法被virtual标记而子类没有重写此方法时,在方法调用时还是调用父类方法


抽象类

抽象类存在自己的构造方法,供子类实例化时调用,但抽象类无法被用户实例化

在C# 中,类中字段如果没有访问修饰符,则默认为private(在Java中,必须存在访问修饰符)

抽象类中可以存在抽象方法与非抽象方法,如果存在抽象方法,则其子类必须重写该抽象方法

对比接口来说,抽象类可以存在非抽象方法(即具体的方法实现),而且C#也是单继承语言,所以只能继承一个类,而可以实现多个接口

注:抽象方法只能存在于抽象类中,而不能存在于非抽象类中

在C#中,abstract修饰的方法在重写是需要使用override关键字


接口

在接口中,方法默认的修饰符是public,这意味着接口中的所有成员(包括方法、属性、事件等)默认都是公开的,即任何实现了该接口的类都必须公开实现这些成员

在类中,属性默认的修饰符为private

在C#的命名规则中,接口多以I开头

子类可以同时继承父类和实现多个接口,但继承需要写在最前面,以逗号分割