数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>

C# 基础接口篇

一、多态复习
使用个new来实现,使用virtual与override
   --》new隐藏父类方法 根据当前类型,电泳对应的方法(成员)
   --》override重写 无论什么情况,都是执行新的方法(成员)

继承是实现多态的一个前提,没有继承多态是不能实现的
父类与子类实现多态
抽象类与子类实现
抽象类不能实例化
抽象类中的抽象方法没有方法体

抽象类的成员有哪些
  -》包含非抽象成员
  -》不能实例化
  -》子类必须实现父类的 抽象方法,除非子类也是抽象类
抽象成员有哪些呢?(凡是与方法有关的都可以抽象)
方法、属性、索引、事件
自动属性与抽象属性
这个字段只需要实现读和写的功能不需要其他控制的时候就可以使用自动属性

二、接口
1)接口的关键字:interface 
2)接口的命名以I开头
3)成员符没有访问修饰符
4)没有方法实现体
5)接口里的成员必须是抽象的
6)接口定义能力即方法 派生类必须实现接口方法,除了抽象类
7)接口的存在就是为了实现多态
8)继承可以解决继承体积庞大的其问题,比如说有一个算法类里面有很多功能很齐全的计算方法,我现在要实现1+1=2的计算,此时如果调用这个功能齐全的类库来实现,那么无疑使大材小用了
也会产生很多的冗余代码,那么就可以考虑用接口来实现,接口的单一原则,接口实现的功能越少越好,一般一个接口实现一个功能,一般接口里面不要超过两个方法

接口可以实现多继承:
语法:
  

[public] [static] class 类名:[基类名,][[接口名,]接口名....]

接口比抽象类还抽象,接口是对功能的抽象

显示实现接口:

  -》为了避免接口的方法名相同

  -》显式实现接口必须由接口类型调用

显示实现接口的方法不能一public修饰,方法名以接口名.方法名

  

interface IInterface1
    {
        void Func();
    }
    interface IInterface2
    {
        void Func();
    }

    class MyTest : IInterface1, IInterface2
    {
        void IInterface1.Func()
        {
            Console.WriteLine("我是IInterface1提供的Func");
        }

        void IInterface2.Func()
        {
            Console.WriteLine("我是IInterface2提供的Func");
        }
    }

  

添加代码段

C# 值类型_引用类型篇

三、值类型、引用类型

值类型就“复制文件”

-》值类型来源于Vluar Type

引用类型就是“复制快捷方式”

->引用类型来源于object

使用ref与out都可以将参数传入方法,并保留在方法中对参数赋值时的影响

即参数在方法中被修改了,方法结束后,结果仍然保留方法中最后那一次被修改的值

ref reference 引用方法中用的是变量的引用,就是快捷方式

Out 参数用来输出,即在方法中对变量的修改就是要传到外边输出的

ref 在使用前要赋值

out 在方法中使用前要赋值

static void Main(string[] args)
{
int num = 0;
Func1(ref num);

int num1;
Func2(out num1);
}

static void Func1(ref int n)
{
n = 10;
}

static void Func2(out int n)
{
n = 10;
}

C# 静态与非静态篇

三、静态与非静态

static修饰的成员就做静态成员

静态成员作用于整个应用程序

    -》在程序里那里都可以调用它

如何定义静态成员?

  -》加static修饰

静态成员与实例成员调用关系?

  -》静态方法、静态类中不要允许直接调用静态成员,如果要调用必须要new对象由对象来调用

如何调用静态成员?

  -》类名.成员名

静态成员属于整个类

实例成员属于对象

当某个类的成员都是静态成员不需要实例化的时候就可以把这个类定义成静态类,在程序中重复使用

static与abstract级别相同

   -》只能由其中一个修饰

与public和internal没有关系

静态类不允许继承

静态类里面不允许有实例成员

静态构造方法

  -》不允许带参数

  -》只允许由static修饰,没有public修饰等

静态构造方法从程序开始到结束只会被执行一次(一访问这个类就会第一个执行静态方法)

Dotnet基础_异常处理篇

四、异常的处理

  1)try-catch

  2)try-catch-finally

  3)tre-finally

try
  {
     //可能出现异常的额代码
  //打开数据库,操作数据等
  //一旦出现异常,就从异常处停下来跳到catch中,tyr中其后的代码就不再执行了
  }
  catch(Exception ex)
  {
      //一旦出现异常,就执行这里的代码
   //一般做日志等
  }
  finally
  {
    // 释放资源
  }

 

异常向上抛,如果上面(调用者)没有(catch)抓住,那么就会再向上面抛,如果上面一直都没有抓住就会抛到系统去,系统就会检索这个异常,给出解决方案

如果系统解决不了就会抛给微软

不管抛异常或者return   finally始终都会被执行,(可以用if判断的错误尽量不要用try-catch)

C#_GC垃圾回收篇

三、GC   垃圾回收

垃圾回收总是从第0代开始回收

每次进行垃圾回收,前一代如果不使用了,就会被清掉,

如果,前一代中,某些对象仍然在使用中,就将其晋升为下一代。

如何自动的释放资源

   -》.net中对象有代的概念,每一个代是有内存范围的

   -》.net中的代有0、1、2三个等级

   -》2代的内存最大

   -》每次创建的对象默认为0代,当对象到达0代满了的时候会自动触动回收第0代

   -》“回收”实际上就是将需要继续使用的对象统一移动到另外一段连续的内存中

   -》所有的地址指向都会发生变化(这个移动有时叫做压缩)

   -》如此操作,当第一代满的时候就会调用回收第一代,并将需要使用的的对象放在第二代里

   -》如此操作,第二代满的时候,就会抛出一个overflow异常

当对象字节数大于85000,此时该对象将存储在大对象托管堆中

在进行垃圾回收的时候,不去考虑大对象区的数据(除非大对象区的数据小于85000)

   21250个int类型的对象==85000字节

      // 16个

            MyClass n1 = new MyClass();

            MyClass n2 = new MyClass();

            MyClass n3 = new MyClass();

            MyClass n4 = new MyClass();

            MyClass temp = n2;

            n2 = null;

            // 0x0012

            // 手动调用垃圾回收器

            System.GC.Collect(0);

            // 会根据你当前系统中内存使用情况进行优化

            n1 = null;

            System.GC.Collect(0);

            System.GC.Collect(1);

            Console.ReadKey();

C# 值类型引用类型内存分配篇

复习 值类型与引用类型

引用类型就是在处理地址

   --》快捷方式与文件的关系

   --》对象在内存中做了什么

32位的计算机用32个2进制位表示一个整数,同时使用32个二进制位来描述一个地址

1、内存空间的分配:分为3个空间

在栈空间中,系统是按高位到低位分配内存空间的(就是从大的数到小的数)

在堆空间中,系统是按低位到高位分配内存空间的(就是从小到大的数)

1)一个内存空间用来存放当前执行方法中的代码

     -》叫线程栈

     -》一个方法一个线程栈

程序在一开始执行就会去检索每个方法当中有哪些变量,并且为这些变量分配内存空间,相当于开辟好意见意见的空房间给这些房间编号(就是地址),

然后把内存里的数据清零(注意是清零相当于把里面的数据变成这样 0x0000,所以程序并没有执行到这个变量之前,光标放到这个变量上去会看到这个变量的值是 0,

但是此时的变量并不是赋值,并不可以用,因为这个0是内存空间里清除数据的0x0000,而不是赋值,等执行了等号之后才会真正地为这个变量赋值)

2)一个空间用来存放对象

       -》托管堆

对象就是一个变量的值,比如说 int num=10;  new person();   这个10和new person();就是对象。

3)存放静态对象,大对象(大于85000字节)等

2、值类型:

  

static void Main()
  {
       int num=10;
  }

  

上面这段代码,程序执行到Main放法系统就会开辟一个线程栈,这个线程栈用来存放这个方法执行的代码,

程序一开始就会检索方法里面的所有变量,然后为int num开辟一个内存,系统会把这个内存里面的数据清除 0x0000,

并且给这个内存空间一个地址(相当于给这个内存空间编了个号)。

值类型的变量直接存在线程栈中,其中的值也存在线程栈中。数据在声明的时候系统就会根据声明的类型开辟相应大小的内存空间。

3、引用类型

    -》引用类型分为两个空间来存储,变量存储在线程栈中,对象存储在托管堆中

class Person()
 {
 }
 static void Main()
 {
    Person p=new Person();
 }

程序一开始在栈空间中开辟一个内存把里面的数据清零(0x0000),然后把这个p存到栈空间里去,当程序执行到main方法里面的时候会先执行new Person();(就是在new对象)

此时在就会在堆空间中开辟一个空间把数据清零,然后分配字段,,构造方法初始化,并产生一个地址,new对象时返回一个地址,这个地址指向了这个对象,然后执行等号赋值,此时赋值是把堆空间中这个对象产生的地址赋给变量p。此时变量P中存的是地址

我们处理的时候其实是对这个地址进行处理。

所以我们在传参的是时候是把变量中的值复制一份传过去,就是把这个地址复制了一份赋给方法中接收的变量,此时在方法中对这个变量是对地址的处理,所以会在外面保留影响

二、对象的创建(new对象的时候其实在内存里面做了很多事)

--》寻找类的继承关系,从上往下计算所有的字段的字节数

--》再把这个数加上8个字节(如果是64位操作系统加16) (这里8个字节方法栈4个指针占4个)

--》然后向操作系统申请空间

--》如果空间已满,返回一个overflow异常

--》如果空间够了就会返回该空间的首地址

--》根据计算出来的长度,会把这一片的内存空间清零

--》Nextobjptr会在原来的地址位置加上刚刚计算出来的数据,得到下一个对象的首地址

--》调用构造方法

多个对象在内存中时连续存储的

时间: 2024-10-23 08:31:03

数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>的相关文章

C# static 字段初始值设定项无法引用非静态字段、方法或属性

问题:字段或属性的问题字段初始值设定项无法引用非静态字段.方法 下面代码出错的原因,在类中定义的字段为什么不能用? public string text = test(); //提示 字段或属性的问题字段初始值设定项无法引用非静态字段.方法 protected void Page_Load(object sender, EventArgs e) { } public string test() { return ""; } 可以通过属性方式调用: public string text

Java深度历险(四)——Java垃圾回收机制与引用类型

Java语言的一个重要特性是引入了自动的内存管理机制,使得开发人员不用自己来管理应用中的内存.C/C++开发人员需要通过malloc/free 和new/delete等函数来显式的分配和释放内存.这对开发人员提出了比较高的要求,容易造成内存访问错误和内存泄露等问题.一个常见的问题是会产生“悬挂引用(dangling references)”,即一个对象引用所指向的内存区块已经被错误的回收并重新分配给新的对象了,程序如果继续使用这个引用的话会造成不可预期的结果.开发人员有可能忘记显式的调用释放内存

Java GC 垃圾回收器的类型小结

阅读了java paper的垃圾回收器类型文章,在此做一个小结,文章部分翻译自java paper gc collector,部分自己做的总结,图片来自网络,在此仅用作理解表达之用. 一.JVM GC 垃圾回收器类型 JVM的垃圾回收器大致分为四种类型: (图片来自网络) 1.串行垃圾回收器  Serial Garbage Collector 串行垃圾回收器在进行垃圾回收时,它会持有所有应用程序的线程,冻结所有应用程序线程,使用单个垃圾回收线程来进行垃圾回收工作. 串行垃圾回收器是为单线程环境而

程序设计基石与实践系列之类型提升、内存分配,数组转指针、打桩和矢量变换

英文出处:Peter Fa?ka: Guide to Advanced Programming in C C语言可用于系统编程.嵌入式系统中,同时也是其他应用程序可能的实现工具之一. 当你对计算机编程怀有强烈兴趣的时候,却对C语言不感冒,这种可能性不大.想全方位地理解C语言是一件极具挑战性的事. Peter Fa?ka 在2014年1月份写下了这篇长文,内容包括:类型提升.内存分配,数组转指针.显式内联.打桩(interpositioning)和矢量变换. 整型溢出和类型提升 多数C程序员以为,

C++变量内存分配及类型修饰符

前言 了解C++程序内存分配,有助于深刻理解变量的初始化值以及其生存周期.另外,变量类型修饰符也会影响到变量的初始化值及其生存周期.掌握了不同类型变量的初始化值及其生存周期,能够让我们设计程序时定义变量时更准确. 内存分配 1.     C++程序的内存布局 现代电脑都是遵循冯诺依曼体系结构,所以C++程序的内存布局也是遵循该体系的.主要包括5个部分,即代码段.数据段.BSS段.堆和栈.. 1.     代码段 代码段(code segment/text segment),通常是指用来存放程序执

String对象内存分配和基本数据类型的默认值与初始化相关问题

题目: 阅读下面代码段,给出以下代码的输出结果. public class TestFunction { static int i; public static void main(String[] args) { String str1 = "abc"; String str = "abc"; String str2 = new String("abc"); System.out.println(str1 == str2); System.ou

C#变量初始化问题:字段初始值无法引用非静态字段、方法或属性

http://www.cnblogs.com/bluestorm/p/3432190.html 问题:字段初始值设定项无法引用非静态字段.方法或属性的问题 下面代码出错的原因,在类中定义的字段为什么不能用? public class Test {public Test(){}public int Age=23;public int temp = Age;//ERROR 字段初始值设定项无法引用非静态字段.方法或属性} C#规定在类内部只能定义属性或者变量,并初始化,不能直接变量引用变量. 在初始

20151024_001_C#基础知识(静态与非静态的区别,值类型和引用类型,堆和栈的区别,字符串的不可变性,命名空间)

1:我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出来类这个概念. 类就是个模子,确定了对象应该具有的属性和方法. 对象是根据类创建出来的. 2:类:语法 [public] class 类名 { 字段; 属性; 方法; } 写好了一个类之后,我们需要创建这个类的对象,那么,我们管创建这个类的对象过程称之为类的实例化.使用关键字new 实例化类===创建类 this:表示当前这个类的对象. 类是不占内存的,而对象是占用内存的. 结构是面向过程的,类是面向对象的,之前没有面向对象的时候

枚举|标志枚举+|(或)和&amp;(与)运算|类型转换|值类型和引用类型|传参|异常|垃圾回收

枚举部分 enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型. 通常情况下,最好是在命名空间内直接定义枚举,以便该命名空间中的所有类都能够同样方便地访问它. 但是,还可以将枚举嵌套在类或结构中.默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1. 例1: //此枚举的默认值是从0开始 enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri}; 例2: //此枚举的默认值是从1开始,下标为3的tue值为7,从下标3开始