C# visual studio 2022 学习2

news2024/11/28 22:35:22

类成员:

  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));
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-tree 设置默认展开指定层级

el-tree默认关闭所有选项&#xff0c;但是有添加或者编辑删除的情况下&#xff0c;需要刷新接口&#xff0c;此时会又要关闭所有选项&#xff1b; 需求&#xff1a;在编辑时、添加、删除 需要将该内容默认展开 <el-tree :default-expanded-keys"expandedkeys":da…

JS+CSS3点击粒子烟花动画js特效

JSCSS3点击粒子烟花动画js特效 JSCSS3点击粒子烟花动画js特效

大数据技术学习笔记(十三)—— HBase

目录 1 Hbase 概述1.1 Hbase 定义1.2 HBase 数据模型1.2.1 HBase 逻辑结构1.2.2 HBase 物理存储结构1.2.3 数据模型 1.3 HBase 基本架构 2 HBase Shell 操作2.1 基本操作2.2 namespace 操作2.3 表操作 3 HBase 原理深入3.1 RegionServer 架构3.2 HBase 写流程3.3 MemStore Flus…

【技术栈】Redis 企业级解决方案

​ SueWakeup 个人主页&#xff1a;SueWakeup ​​​​​​​ 系列专栏&#xff1a;学习技术栈 ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ 个性签名&…

C# 使用OpenCvSharp4将Bitmap合成为MP4视频的环境

环境安装步骤&#xff1a; 在VS中选中项目或者解决方案&#xff0c;鼠标右键&#xff0c;选择“管理Nuget包”&#xff0c;在浏览窗口中搜索OpenCVSharp4 1.搜索OpenCvSharp4,选择4.8.0版本&#xff0c;点击安装 2.搜索OpenCvSharp4.runtime.win,选择4.8.0版本&#xff0c;点…

vue3 + vite 实现一个动态路由加载功能

假设后端返回的格式是这样子 {"menu": [{"path": "/admin","name": "adminLayout","redirect": "/admin/index","componentPath": "/layout/admin/index.vue","children&quo…

Could not locate zlibwapi.dll. Please make sure it is in your library path!

背景 运行PaddleOCR时&#xff0c;用的CUDA11.6配的是cuDNN8.4。但是运行后却报错如下。 解决手段 去网上找到这两个文件&#xff0c;现在英伟达好像不能下载了&#xff0c;但是可以去网盘下载。然后把dll文件放入CUDA11.6文件下的bin目录&#xff0c;而lib文件放入CUDA11.6文…

基于YOLOv8的航空遥感飞机小目标检测

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的航空遥感飞机小目标检测&#xff0c;阐述了整个数据制作和训练可视化过程 1.YOLOv8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先…

js检测数据类型方式(typeof instanceof Object.prototype.toString.call())

typeof 使用 typeof 检测数据类型&#xff0c;首先返回的都是一个字符串&#xff0c;其次字符串中包含了对应的数据类型&#xff1b; 缺点&#xff1a; typeof null "object"不能具体细分是数组、正则还是对象中其他值&#xff0c;使用 typeof 检测数据类型对于对…

微服务day03 -- Docker

1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。 在数百上千台服务中重复部署&#xff0c;环境不一定一致…

59、服务攻防——中间件安全CVE复现IISApacheTomcatNginx

文章目录 中间件——IIS漏洞中间件——Nginx漏洞中间件——Apache中间件——Tomcat 中间件&#xff1a;IIS、Apache、Nginx、Tomcat、Docker、Weblogic、JBoss、WebSphere、Jenkinsphp框架&#xff1a;Laravel、Thinkphppythonl框架&#xff1a;Flaskjs框架&#xff1a;jQueryj…

vue+elementui中table实现单选行功能

el-table插件可以选择行&#xff0c;但是只能多选&#xff0c;而项目中有单选的需求。 效果如下图所示&#xff0c;点击行或者点击复选框都可以选中行&#xff08;高亮&#xff0c;复选框选中&#xff09;&#xff0c;并且每次只选中当前行&#xff0c;之前选中的行清空。点击标…

Panasonic松下PLC如何数据采集?如何实现快速接入IIOT云平台?

在工业自动化领域&#xff0c;数据采集与远程控制是提升生产效率、优化资源配置的关键环节。对于使用Panasonic松下PLC的用户来说&#xff0c;如何实现高效、稳定的数据采集&#xff0c;并快速接入IIOT云平台&#xff0c;是摆在他们面前的重要课题。HiWoo Box工业物联网关以其强…

TikTok云手机是什么原理?

随着社交媒体的快速发展和普及&#xff0c;TikTok已成为全球最受欢迎的短视频平台之一&#xff0c;吸引了数以亿计的用户。在TikTok上&#xff0c;许多用户和内容创作者都希望能够更灵活地管理和运营多个账号&#xff0c;这就需要借助云手机技术。那么&#xff0c;TikTok云手机…

通过el-table实现表格穿梭框

element-ui自带的el-transfer界面比较简单&#xff0c;通过el-table实现表格形式的穿梭框功能 首先是效果图 示例图样式比较简单&#xff0c;但是el-table是完全通过div包裹的&#xff0c;所以里面可以自己添加更多的其他组件实现想要的功能 <div style"display: flex…

微信小程序 ---- 慕尚花坊 结算支付

结算支付 01. 配置分包并跳转到结算页面 思路分析&#xff1a; 随着项目功能的增加&#xff0c;项目体积也随着增大&#xff0c;从而影响小程序的加载速度&#xff0c;影响用户的体验。 因此我们需要将 结算支付 功能配置成一个分包&#xff0c; 当用户在访问设置页面时&a…

鸿蒙Harmony应用开发—ArkTS声明式开发(画布组件:Path2D)

路径对象&#xff0c;支持通过对象的接口进行路径的描述&#xff0c;并通过Canvas的stroke接口或者fill接口进行绘制。 说明&#xff1a; 从 API Version 8 开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 addPath addPath(path: path2D,…

【Web技术应用基础】HTML(1)——简单界面

题目1&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Hello world</title></head> <body bgcolor"F6F3D6"><!--用HTML语言向世界打声招呼吧&#xff01;--><h1 align&…

windows系统下python进程管理系统

两年来&#xff0c;我们项目的爬虫代码大部分都是放在公司的windows机器上运行的&#xff0c;原因是服务器太贵&#xff0c;没有那么多资源&#xff0c;而windows主机却有很多用不上。为了合理利用公司资源&#xff0c;降低数据采集成本&#xff0c;我在所以任务机器上使用anac…

如何解决node-sass下载用的还是过期的淘宝源?

下载node-sass发现报错过期的证书 把npm的淘宝源换成最新的https://registry.npmmirror.com后发现还是指向了以前的淘宝源&#xff0c;看到一位博主说&#xff0c;单改npm源不够还要改下载node-sass的源&#xff0c;再次搜索另外一位博主提供了命令npm config ls可以使用它来查…