C# visual studio 2022 学习2

类成员:

  1.字段成员 字段只是类中声明的一个变量,用来在对象中存储信息。

(1).静态字段 使用static关键字修饰的就是静态字段,静态字段属于类而不属于某个类实例,对它的访问使用“类名.静态字段名” ,不能使用“对象名.静态字段名”的格式。 静态字段通常用来保存当前类的实例个数

例3-2:编写一个类,使用静态字段计算类的实例数量。
public class theclass
{ public theclass()
  {
      count++;  //计数器增1
  }
   public void showcount()
  {
     Console.WriteLine(“实例数为:” + count );
   }
   private static int count=0; //显式赋初值
}
public class Test
{
    public static void Main()
   {
      theclass class1=new theclass();
      class1.showcount();
      theclass class2 =new theclass();
      class2.showcount();
    }
}

(2).只读字段    当字段声明中包括readonly修饰符时,该字段成为只读字段。只能在声明只读字段的同时赋初值。其他任何时候都不允许为只读字段赋值。 


public class Class1{
public readonly string str1=@”I am str1”;}
执行下面代码:
Class1 c1=new Class1();
Console.WriteLine(c1.str1);
//c1.str1=“Change readonlyfiled”;错误
如果在类定义中显式添加一个构造函数,可以在构造函数中改变只读字段的值。
Public class Class1
{Public readonly string str1=@”I am str1”;
  public Class1(){ str1=“initialized by constructor!”;}
}

2.方法成员 方法成员的本质就是在类中声明的函数,描述类能够“做什么”。

参数传递

C#编程语言支持的参数传递方式包括:

 1.值传递:方法中的变量是传入变量的一个拷贝,方法中对形参做的修改,不会影响方法外面的实参。    

(1) 对于值类型数据,值传递就是传递了变量的值。    

(2) 对于引用类型数据,值传递传递的是引用的值,即方法中的形参和方法外的实参将指向同一对象。因此,通过形参也能修改对象的实际内容。  

  • 总结1.(1)(2)就是:

简单类型(int ,double,char),enum类型,struct类型,string类型——>都是值类型

class——>引用类型 

注意:string比较特殊,属于值类型。这里把s2看做实参,s看做形参。

string s = "abc";
            string s2 = s;
            s = "jc";
            Console.WriteLine(s);
            Console.WriteLine(s2);
  • 代码例子:

test1类中有两个同名不同参的方法,这叫重载;

因为是test2是类,所以是引用类型的值传递,改变实参;

这里我一开始每个writeline后面都用了readline所以只出一个结果,只有我不断输入值,才会更新输出,事实上只用在静态Main里面(C#是用Main哦)最后一句放readline即可。

using System;

namespace cs
{
    public class test1
    {
        public void valdiliver(int x)
        {
            x += 5;
            Console.WriteLine(x);
           // Console.ReadLine();
        }
        public void valdiliver(test2 test)
        {
            test.str += "changed!";
            Console.WriteLine(test.str);
            //Console.ReadLine();
        }
    }
    public class test2
    {
        public string str = "this string";
    }
    public class Solution
    {
        static void Main(string[] args)//这是C#的Main方法
        {
            test1 a = new test1();
            test2 b = new test2();
            int c = 1;
            Console.WriteLine(c);
           // Console.ReadLine();
            a.valdiliver(c);
            Console.WriteLine(c);
            //Console.ReadLine();

            Console.WriteLine(b.str);
           // Console.ReadLine();
            a.valdiliver(b);
            Console.WriteLine(b.str);
            Console.ReadLine();
        }

    }
}

2.地址传递:方法中的变量是传入变量的一个引用,方法中对形参做的修改,也会影响方法外面的实参。    

(1) 引用参数ref:由调用方法初始化参数值。

很多情况下,我们要使用参数的引用传递。引用传递是传递变量的地址,使得形参和实参指向同一内存空间,方法中对于形参的修改,实际上就是对于实参的修改。 由调用方法初始化参数值。实参、形参中ref不能省 。   

(2)输出参数 out:被调用方法初始化参数值,可以不用初始化就作为参数传递给方法。

中级特性

面向对象的程序设计的三个核心概念:封装、继承、多态

1.封装

2.继承:

(1)有这四种方式:父调父;子调父:子类对象可以调父类所有方法;父调子;子调子

看一些例子:

  • 子调父的方法

如果儿子有跟父亲同样的方法名,要调父类的那个方法,用base.方法名;如果子类没有,就直接用方法名。

class Car
{
    public Car()
    { }
    protected void f() { Console.WriteLine("aaa"); }
}
class TrashCar : Car
{
    public TrashCar() { }
    void f() { Console.WriteLine("bbb"); }
    public void f1() { base.f(); f(); }//这里前面调父,后面调子
}
class MyApp
{
    static void Main()
    {
        TrashCar myCar = new TrashCar();
        myCar.f1();
    }
}

using System;

namespace cs
{
    public class test1
    {
        public void f()
        {
            Console.WriteLine("test1.....");
        }
    }
    public class test2:test1
    {
        public void f()
        {
            Console.WriteLine("test2.....");
        }
    }
    public class Solution
    {
        static void Main(string[] args)//这是C#的Main方法
        {
            test1 a = new test1();
            a.f();

            

            Console.ReadLine();
        }

    }
}

object声明对象:由于C#中System.Object类是所有类的祖先,所以可以用Object类型的引用指向所有类型的对象。

Object a = new fu();
Object b=new zi();//或者a=new zi;
a.f();
b.f();//报错

3.多态:一个函数可以从父类和子类的入口进去、多态是最大范围的对同名函数的控制

(1)声明用父类,给实例new时用子类,实际去的是父类的入口;

这个叫做继承时的多态

public class fu
{
    public void f() { Console.WriteLine("fu"); }
}
public class zi:fu
{
    public void f() { Console.WriteLine("zi"); }
}
static void Main(string[] args)
{
    fu []a = new fu[3];
    a[0]= new fu();
    a[1]=new zi();
    a[0].f();
    a[1].f();
    Console.ReadLine();
}
//输出
//fu
//fu

(2)(静态)编译时的多态:是通过重载完成的,重载(函数名相同,参数不同)。

这个就是类里写了两个同名同返回的函数,只是参数不同,所以调用函数时就根据参数不同调,而动态多态就是父类和子类各有同名同返回同参,完全一样。

(3)(动态)运行时的多态:是通过虚函数完成的。父类方法加virtual,子类方法加override表示将该方法覆盖;父类子类都加virtual就没用了

public class fu
{
    public virtual void f() { Console.WriteLine("fu"); }
}
public class zi:fu
{
    public override void f() { Console.WriteLine("zi"); }
}
static void Main(string[] args)
{
    fu []a = new fu[3];
    a[0]= new fu();
    a[1]=new zi();
    a[0].f();
    a[1].f();
    Console.ReadLine();
}
//输出
//fu
//zi
fu a = new fu();
fu b=new zi();
a.f();
b.f();
//fu zi本来用父类声明和子类给实例,从父类入口入,但是这里还是被覆盖了

所以可见覆盖和重载的区别:

相同点:       都涉及两个同名的方法。 不同点: 1.类层次 (1).重载涉及的是同一个类的两个同名方法; (2).覆盖涉及的是子类的一个方法和父类的一个方法,这两个方法同名。 2.参数和返回值      (1).重载的两个方法具有不同的参数,可以有不同返回值类型;      (2).覆盖的两个方法具有相同的参数,返回值类型必需相同。

就近法则:有父子孙三级,各级都有同名同返回同参的方法;

在子类方法中访问成员(成员变量、成员方法)满足这个顺序

  • 先子类局部范围找
  • 然后子类成员范围找
  • 然后父类成员范围找,如果父类范围还没有找到则报错。
 public class fu
 {
     public virtual void f() { Console.WriteLine("fu"); }
 }
 public class zi:fu
 {
     public override void f() { Console.WriteLine("zi"); }
 }
 public class sun : zi { 
     public override void f() { Console.WriteLine("sun"); }
 }

 static void Main(string[] args)
 {
     sun b= new sun();
     b.f();//显然输出sun
     Console.ReadLine();
 }
public class fu
{
    public virtual void f() { Console.WriteLine("fu"); }
}
public class zi:fu
{
    public override void f() { Console.WriteLine("zi"); }
}
public class sun : zi { 
    //public override void f() { Console.WriteLine("sun"); }
}

static void Main(string[] args)
{
    sun b= new sun();
    b.f();//输出zi
    Console.ReadLine();
}

new:

若覆盖时没有使用virtual和override关键字,则称子类的方法隐藏了父类的方法。此时编译器报警告。若要消除掉警告,可以使用new修饰符。

不加New的话,会有警告

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs1
{
    internal class Program
    {
        public class fu
        {
            public void f() { Console.WriteLine("fu"); }
        }
        public class zi:fu
        {
            public new void f() { Console.WriteLine("zi"); }
        }
        public class sun : zi { 
            public new void f() { Console.WriteLine("sun"); }
        }

        static void Main(string[] args)
        {
            fu a = new fu();
            a.f();//输出fu
            sun b= new sun();
            b.f();//输出sun
            Console.ReadLine();
        }
    }
}

但要永远遵循“父声明,子给实例,从父类入口进,即调父类方法”

sealed:在虚方法上加这个修饰符;比如子某个方法sealed了,那么孙就不能再对这个方法重写(即改为虚方法)。

例:记得加virtual和override

public class fu
{
    public virtual void f() { Console.WriteLine("fu"); }
}
public class zi:fu
{
    public sealed override void f() { Console.WriteLine("zi"); }
}
public class sun : zi { 
    public override void f() { Console.WriteLine("sun"); }
}

抽象类与接口

抽象类就是把要变成抽象类的类class前面加一个abstract

接口定义:

接口成员访问方式是public,但是不能写出这个修饰符,即不允许public void f();

也不能声明出构造方法,即不能出现实例构造函数void f(){};

正确的:

 interface IA//A表示这个接口的名字,I表示这是一个接口
  {
      void f();
  }

接口上的二义性:例子

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs1
{
    interface IA//A表示这个接口的名字,I表示这是一个接口
    {
        void f();
    }
    interface IB
    {
        void f();
    }
    class A: IA,IB { 
        public void f() { Console.WriteLine("接口IA"); } //类中重写接口中的方法必须用public,不然做不了
        void IB.f() { Console.WriteLine("接口IB"); }//显式调用IB中的方法

    }
    class Program
    {
         static void Main(string[] args) {
            IA a=new A();//不需要as了
            IB b = new A(); //声明接口是调用哪个的关键
            a.f();//输出接口IA
            b.f();//输出接口IB
            Console.ReadLine();
        }
    }
}

总结:声明对象时的接口很重要,“继承”接口的类A中的方法更重要

但声明时更重要,实验过了,如果声明是用IA,A类中是IB.f(),那就调public f()

如果是IA.f(),先调IA.f()。如果是IB.f(),那么只有用IB接口声明对象才能调到IB接口。

new哪个类也可以改变接口怎么写

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs1
{
    interface IA//A表示这个接口的名字,I表示这是一个接口
    {
        void f();
    }
    interface IB
    {
        void f();
    }
    class A: IA,IB { 
        public void f() { Console.WriteLine("接口IA"); } //类中重写接口中的方法必须用public,不然做不了
        void IB.f() { Console.WriteLine("接口IB"); }//显式调用IB中的方法

    }
    class B : IA,IB {
        public void f() { Console.WriteLine("类B走的接口IA"); } //类中重写接口中的方法必须用public,不然做不了
        void IB.f() { Console.WriteLine("类B走的接口IB"); }
    }
    class Program
    {
         static void Main(string[] args) {
            IA a=new A();
            IA b = new B(); 
            a.f();//输出接口IA
            b.f();//输出类B走的接口IA
            Console.ReadLine();
        }
    }
}

实际问题:同学A还是同学B收作业问题

接口中一个方法就是收作业方法,两个同学作为类继承这个接口,是A还是B收作业再看

需要做一个走这个接口的通道(也可以像上面的例子中直接用a.f()还是b.f())

为什么要这个接口?因为工作中如果多写一个类多写一个方法很冗余,或者有的类不需要继承这个接口,然后你再写一个接口把这个工程都改了,能行吗

有一个Person类为什么要?就是Person类可以是A同学B同学类的父亲类,这样的话我就不用再改变new A() 还是new B() 时的语句,直接再Person类中搞(太难了不写了)

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs1
{
    interface collecthomework
    {
        void f();//收作业的方法
    }
    class A: collecthomework{ 
        public void f() { Console.WriteLine("接口收作业,A收"); } //类中重写接口中的方法必须用public,不然做不了
    
    }
    class B : collecthomework {
        public void f() { Console.WriteLine("接口收作业,B收"); } //类中重写接口中的方法必须用public,不然做不了
    }
    class Program
    {
        static void docollecthomework(collecthomework work)//执行这个通道需要搞一个做这个接口的通道
        {
            work.f();
        }
         static void Main(string[] args) {
            collecthomework a= new A();
            docollecthomework (a);
            Console.ReadLine();
        }
    }
}

可以感觉到接口类似取代了基础的父类,而且比父子之间调的更便利,只要同名畅通无阻调(老师说:要学会丢弃旧方法,用新方法,比如子类的override重写和接口,都是很好的方法)

接口中的方法少些带参的

上一个例子的docollecthomework函数如果函数参数是接口数组,就很牛,因为类似子类的方法全部都在这个接口数组之下,答案都在这个数组里啊

计算不同图形的面积的例子:

public class MyApp
{
    public static double SumAreas(ICalAreaAndVolumn[] array)//这个
    {
        double tot = 0.0;
        for (int i = 0; i < array.Length; i++)
        { tot += array[i].GetArea(); }
        return tot;
    }
    public static void Main()
    {
        Sphere sp = new Sphere(2);
        Cylinder cd = new Cylinder(2, 10);
        Cone cn = new Cone(2, 20);
        ICalAreaAndVolumn[] array = { sp, cd, cn };
        Console.WriteLine("total arears = {0}", SumAreas(array));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/469467.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

28-2 文件上传漏洞 - 双写绕过

环境准备&#xff1a;构建完善的安全渗透测试环境&#xff1a;推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、双写绕过原理 在代码编写过程中&#xff0c;双写绕过原理指的是只对黑名单中的内容进行一次空替换。由于只进行一次替换&#xff0c;导致了双写绕过的情况…

数据结构从入门到精通——排序的概念及运用

排序的概念及运用 前言一、排序的概念排序稳定性内部排序外部排序 二、排序运用三、常见的排序算法四、排序性能检测代码srand()clock() 五、oj排序测试代码 前言 排序是将数据按照一定规则重新排列的过程&#xff0c;常见规则有升序、降序等。排序算法如冒泡排序、快速排序等…

JavaScript中的继承方式详细解析

什么是继承 继承是面向对象编程中的一个重要概念&#xff0c;它指的是一个对象&#xff08;或类&#xff09;可以获得另一个对象&#xff08;或类&#xff09;的属性和方法。在继承中&#xff0c;被继承的对象通常称为父类&#xff08;或基类、超类&#xff09;&#xff0c;继…

C++关键字:static

文章目录 一、static的四大用法1.静态局部变量2.静态全局变量3.静态函数4.类中的 静态成员变量、静态成员函数 一、static的四大用法 1.静态局部变量 延长局部变量的生命周期。 1.与普通的局部变量不同&#xff0c;局部静态变量在函数调用结束之后&#xff0c;不会被销毁&am…

中国银联订单支付产品实施指南(2022.A 版)

为落实总行提出以银行账户为基础&#xff0c;全面提升对小微企业、民营企业的支付结算服务能力和水平的总体思路要求&#xff0c;践行支付为民&#xff0c;银联提出建设订单支付产品&#xff0c;通过深度融合企业线上线下支付场景&#xff0c;充分赋能商业银行B2B业务支付结算&…

数据结构奇妙旅程之红黑树

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

“团团活力圈”--“书香润童心 阅读伴成长”青少年读书分享活动

书籍是人类进步的阶梯&#xff0c;读书能够陶冶人的情操、开阔眼界&#xff0c;同时&#xff0c;通过读书&#xff0c;能够帮助人们增长知识&#xff0c;培养正确的人生观、价值观。为了帮助青少年多读书&#xff0c;感受读书的乐趣&#xff0c;3月17日&#xff0c;在共青团中央…

【代码】YOLOv8标注信息验证

此代码的功能是标注信息验证&#xff0c;将原图和YOLOv8标注文件&#xff08;txt&#xff09;放在同一个文件夹中&#xff0c;作为输入文件夹 程序将标注的信息还原到原图中&#xff0c;并将原图和标注后的图像一同保存&#xff0c;以便查看 两个draw_labels函数&#xff0c;分…

Ubuntu Desktop - Desktop

Ubuntu Desktop - Desktop 1. Amazon2. Ubuntu Software3. Desktop4. 系统桌面快捷方式5. 用户桌面快捷方式References 1. Amazon Amazon -> Unlock from Launcher 2. Ubuntu Software Installed -> Games -> Remove 3. Desktop /home/strong/Desktop 4. 系统桌面…

Java项目:65 ssm社区文化宣传网站+jsp

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本选题则旨在通过标签分类管理等方式&#xff0c; 实现管理员&#xff1b;个人中心、用户管理、社区新闻管理、社区公告管理、社区活动管理、…

React——开发者工具

浏览器插件&#xff1a;谷歌浏览器插件react-devtools 方式1&#xff1a;chrome应用商店添加 方式2&#xff1a;下载安装包放在浏览器上

32串口学习

基于之前的GPIO等工程&#xff0c;后面的上手难度就简单多了&#xff0c;主要是相关寄存器的设置。 void USART1_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph…

可视化图表:雷达图的全面介绍,一篇就够了。

一、什么是雷达图 雷达图&#xff08;Radar Chart&#xff09;是一种可视化图表&#xff0c;也被称为蛛网图、星形图或极坐标图。它以一个中心点为起点&#xff0c;从中心点向外延伸出多条射线&#xff0c;每条射线代表一个特定的变量或指标。每条射线上的点或线段表示该变量在…

Linux常用命令之搜索查找类

1.1find查找文件或目录 1&#xff09;基本语法 find [搜索范围] [ 选项] find -name&#xff1a;按照名字查找 find -user&#xff1a;按用户相关查找 find -size&#xff1a;按照文件大小查找 1.2locate快速定位文件路径 经验技巧&#xff1a;由于locate指令基于数据库进行…

Ubuntu上搭建TFTP服务

Ubuntu上搭建TFTP服务 TFTP服务简介搭建TFTP服务安装TFTP服务修改配置文件 重启服务 TFTP服务简介 TFTP是一个基于UDP协议实现的用于在客户机和服务器之间进行简单文件传输的协议&#xff0c;适用于开销不大、不复杂的应用场合。TFTP协议专门为小文件传输而设计&#xff0c;只…

信息学奥赛之C++ cstdlib – 概览

什么是 C cstdlib&#xff1f; C 标准库头文件 (cstdlib in C) 是 C 程序员使用最广泛的库头文件。即&#xff1a;standard librarian。它定义了一系列函数和宏&#xff0c;以实现跨团队、跨平台的高效且具有卓越表现的标准化 C 代码。 C 是一种广受欢迎的程序语言&#xff0c…

总结

文章目录 1. GateWay&#xff1a;100102. Docker3. ES&#xff1a;海量数据的存储、搜索、计算3.1 数据搜索3.2 数据同步 4. 微服务保护&#xff1a;Sentinel4. 分布式事务&#xff1a;&#xff08;二阶段提交&#xff09;5. Redis6. 多级缓存 1. GateWay&#xff1a;10010 2. …

【工具】Mermaid + 大模型画流程图

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 引入使用画TCP三次握手了解历史人物 总结 引入 最近看面试文章关于TCP三次握手和…

【数据结构】链表力扣刷题详解

前言 题目链接 移除链表元素 链表的中间结点 反转链表 分割链表 环形链表的约瑟夫问题 ​ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 移除链表元素 题述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请…

基于python的在线学习与推荐系统

技术&#xff1a;pythonmysqlvue 一、系统背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这样的大…