• C#和java之间的一些差异与共性


    C#与java之间的一些共性和差异整理

    隐藏:
    与java中的重写几乎一致,但是需要添加new关键字让编译器知道,否则会有警告


    虚方法:
    1.声明为virtual的方法就是虚方法,在子类中使用override进行重写,当程序发现该方法是虚方法时,会去寻找子类中是否重写了该方法,如果被重写了,那么就调用子类中的方法,所以重写是多态实现的一种重要的方式,也称为动态绑定,而重载则是在程序编译阶段就进行的,所以叫静态绑定,也是编译前绑定
    2.重写虚方法必须具有相同的可访问性,基类中的虚方法不能是private的
    3.不能重写static方法或者非虚方法,覆盖使用的是new关键字。而非override
    4.方法、属性、索引器、事件都可以用虚方法或者重写
    5.与java中的抽象方法类似,但是虚方法可以拥有方法体,同时不一定要被重写,抽象方法则必须被重写


    字段和属性:
    1.通过设置属性的方式,来创造类似javabean中的set和get方法、
    属性是public的。字段是private的,属性的名称要自己设置,但是最好和字段名字要相近,首字母大写,同时属性的数据类型和字段的数据类型要一致,可以使用CTRL+R+E的方式进行快捷封装。


    2.将set属性删除,就可以让属性成为只读属性,对字段进行保护,get可以获取字段的值。set和get类似于java中的方法,可以在set方法中对属性的值进行检查,过滤,防止一些不合理的数据出现。


    值类型和引用引用类型(值传递和引用传递):
    1.基本数据类型,int bool char double等为值类型,是存储在栈中的(内存),当作用域结束时销毁,所以存储速度快
    ,对于值类型,有关赋值等相关的操作是copy了一份值的副本,因而其中一方更改不会影响到另外以防,例如A=1 B=A 修改A的值和B的值互不影响,各自进行管理,


    2.引用类型: 类(String类型属于类),数组,接口等对象,就是引用类型,它们是存储在堆中的(物理硬盘),所以速度会较慢,但是他们的赋值操作,是会互相影响的。 例如: Dog dog=new Dog();    Dog dog2=dog; 这里的操作是创建了一个dog对象,同时将这个对象赋值给了dog2引用。
    这里的dog 和dog2 是对象的引用,是存储在栈中的, 而new Dog()这个真正的对象中包含的数据是存储在堆中的。
    所以dog和dog2指向的是同一个对象,因而如果dog或dog2对这个new出来的dog对象进行了修改,那么dog和dog2在调用其中的属性的时候,都是调用的修改后的属性。 


    例子:可以理解成,两个小朋友一人有一个棒棒糖(值类型),各自吃各自的,自己的吃
    完了。对方的不一定吃完。   然后两人各有一个遥控器,都能对电视机进行控制,当一个人切到了天线宝宝的节目的时候,另外一个人看到的也是天线宝宝,即引用传递修改的是同一个东西,而值传递修改的是两个东西,是各自的副本


    结构和类:
    1.结构中的字段不能有初始值,类中的字段可以有初始值,结构中的字段可以和类一样有属性,结构和类都能有构造方法,但是结构中不能有显式的无参构造方法,可以有带参的构造方法,同时要为结构中的所有字段赋值,如果有一个没有赋值,都会报错。
      类中则无参带参都可以有,同时没有必须为所有字段赋值的限定。


    2.结构可以不必实例化,直接就能访问它的属性和方法。 类则不能。 


    3. 结构不支持继承,类支持继承,编译器会自动定义结构的无参构造方法


    枚举类型:属于值类型,在枚举中不能定义字段属性和方法,枚举是从0递增的增数值,
    限定了某些类型的取值范围,例如性别。可以防止错误的输入
    赋值:枚举名.枚举中的属性名  例如 Gender.男 或者使用强制类型转换(Gender)0


    引用传参和值传参(引用传递和值传递):
    1.按引用传参,方法修改形参,通常实参也会被修改,
    2.按值传参,方法修改形参,实参不会被修改


    ref关键字:
    添加ref关键字,可以让至传递的值类型变量,转化为按引用传参,但要注意在传递的双方都要带上ref修饰(声明和调用时),同时属性不允许作为ref关键字修饰的参数,所以需要单独声明一个变量来存储属性的值。


    out关键字:
    用来获取结果。可以视作return的补充。


    调用顺序:
    1.先实例化父类中的成员----然后调用父类中的构造函数---然后调用子类中的实例成员----然后调用子类的构造函数
    2.使用base()可以进行显式的调用父类的构造函数,使用this()则调用当前子类自己的构造函数,括号中可以带参也可以是无参的


    抽象类和抽象方法:
    与java基本类似,抽象成员必须是方法属性时间索引器,


    密闭类和密闭方法:
    sealed修饰,作用类似于java中的final,如果要修饰变量,则使用const


    接口:
    与java的语法规则基本一致,但是在继承了一个类同时实现多个接口的时候,必须将继承的类摆在:的最前面一个


    静态成员,静态类:
    1.静态成员不能访问实例成员因为实例成员需要new出对象以后才会被创建,所以实例成员可以访问静态成员,静态成员无法访问实例成员


    2.静态类不能创建实例,也不能被继承,可以定义一个静态的构造函数,主要应用于基础类库,和扩展方法


    如何扩展方法:
    如果有源代码,直接添加新的方法。
    如果不能修改,但也不是密闭类,可以通过子类来进行扩展
    如果以上操作都无法实现,则可以使用静态类进行扩展
    1.扩展方法所属的类必须是一个静态类,2.同时该方法本身也必须是一个静态方法
    3.扩展方法的第一个参数类型必须是this+类名
    例子:   static class Guid{
                 static public void HowTo(this Dog dog){


                    }
           
              } 
    最后直接通过 Dog dog =new Dog();
               dog.howTo();
    就可以对扩展的方法进行访问了,类似于这个方法就是原生在Dog类(需要被扩展额外方法的类)中的。


    自定义转换:
    1.隐式转换必须是静态的公共方法并且使用 implicit operator关键字
    : public static implicit operator Cat(Dog dog) 
    {  
             return new Cat();
      }
    括号外的对象是传入的参数是想要被隐式转换后的对象类型


    2.显式转换与隐式转换的定义基本一致,差别在于使用explicit关键字
    : public static explicit operator Dog(Cat cat)

             return new Dog();
     }
     括号外的对象是传入的对象想要被显式转换后的对象类型


    3.重载运算符:利用现有的运算符,针对自定义的类或者结构定义某种运算操作,(不能是自己创造的运算符,不能是预定义的类型如int String等)。重载运算符可以简化自定义类型的操作,更加方便和直观。
      当运算符是一元运算符的时候 操作数必须是类或者结构中的一种,如果运算符是二元的时候,两个操作数中必须有一个是类或结构


    public static Pet operator ++(Pet pet){
    ++Pet.age;
    }
     pet++; 此时pet对象因为重载了++运算符,所以,进行pet++的时候,是让pet的age进行了+1
     pet.showAge();


    泛型,约束:
    通过约束,更好的利用泛型,泛型参数可以有多个即T1 T2 T3 
    同时约束就是利用where语句对特定的泛型进行约束,
    void  home<T> where T: (1.主约束 2.接口约束 3.构造约束)
    主约束只能有一个可以是某个具体的类名,class,结构, 接口约束可以有任意个
    当具体到某个类名的时候,传入的只能是这个类的类型的对象,class则表示必须传入一个类类型对象,即不能是int之类的值类型。当确定了传入的类之后,就可以直接调用传入的这个主约束中的方法,接口也是同理,当传入构造约束以后。就可以在泛型方法中创建实例对象了。


    集合:
    Arraylist是动态数组,什么都能放,是一维的,但是也是类型不安全的,所以有了List<T>泛型,但是这里就会存在装箱和拆箱的操作,性能上有损失两者都有add remove,count等方法,可以通过索引来访问和删除指定索引位置的数据


    Dictionary字典,类似于java中的Map。它的数量也是count方法,添加的时候需要添加两个,一个是key一个是value。访问则直接通过key来进行访问,更加的方便管理,但是


    stack栈是先进后出,类似只有一个开口的容器,
    pop出栈,push入栈,peek获取栈顶元素


    queue队是先进先出,类似于水管,两头都开口的容器。
    dequeue 出队, enqueue入队


    委托:
    委托就是持有一个或者多个方法的对象!并且该对象可以执行可以传递,使用delegate声明
    可以将对象的方法赋给委托对象
    delegate void A();
     A del=dog.speak;
     del+=dog.run;


    使用方式:与使用函数一样直接使用委托名加括号的方式del(); 
      委托可以持有多个方法,调用一次,
    就可以把委托中的方法全部执行一遍


    Lambda表达式:即匿名的委托
    del=()=>{}
    del+=()=>{
    方法具体.....
    }


    事件:可以理解为是一种封装的,受限制的委托
    1订阅:关注某个事件发生
    2发布:通知某个事件发生
    3注册:想要在事件发生时被通知,必须要注册
    触发,即当事件发生时,调用订阅者的注册函数,注册就是告诉发布者应当调用哪个注册函数


    事件的订阅 newdog += 方法  表示关注  newdog -= 方法 表示取消关注,方法可以是实力方法,静态方法,匿名方法,Lambda表达式
    其中的newdog就是事件名,即想要关注的是哪个事件


    事件触发 if(newdog!=null){
              newdog();
      }
    对事件进行判断,如果不为空,则代表有关注者,也就是被订阅了,那么就执行这个委托事件


    public delegate void handler(); //定义一个委托类型
    public static event handler newdog;       //定义一个委托事件


    在需要进行事件触发的地方进行事件的判断,与触发


    同时进行事件的订阅,也就是注册 dog.newdog += 方法
    ---------------------
    作者:YXJHASADREAM
    来源:CSDN
    原文:https://blog.csdn.net/qq_36854407/article/details/79188865
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    一些 Ubuntu 使用的小技巧
    体验 Web 自动化测试工具 Selenium
    CentOS 7 上安装 Nginx
    Windows查看端口占用情况
    Windows远程登录提醒:由于没有远程桌面授权服务器可以提供许可证,远程会话连接已断开。请跟服务器管理员联系。
    Vue动态的改变css样式
    centos7 U盘安装卡在 starting dracut initqueue hook Reached target Basic System
    用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本;
    Linux修改SSH默认的端口号
    Centos编译安装新版本Git
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/10016881.html
Copyright © 2020-2023  润新知