【转载】C#扫盲之:静态成员、静态方法、静态类、实例成员及区别

【转载】C#扫盲之:静态成员、静态方法、静态类、实例成员及区别

文章目录

1.静态成员、实例成员

2.静态类

3.类的静态成员和非静态成员区别

————————————–分割线———————————————

1.静态成员、实例成员

1.1定义及说明

  数据成员:

静态成员:静态成员变量是和类相关联的,可以作为类中”共”有的变量(是一个共性的表现),他不依赖特定对象的存在,访问的时候通过类名加点操作符加变量名来访问.

实例成员:实例成员变量是和对象相关联的,访问实例成员变量依赖于实例的存在.

  函数成员:
静态方法:静态方法是不属于特定对象的方法,静态方法可以访问静态成员变量和静态方法;静态方法不可以直接访问实例变量和实例方法,可以间接调用,首先要创建一个类的实例,然后通过这一特定对象来调用静态方法;

实例方法:一个实例方法的执行与特定对象关联,他的执行需要一个对象存在。实例方法可以直接访问静态变量和实例变量,当多个实例对象存在时,内存中并不是存在美个特定的实例方法的拷贝,而是,相同类的所有对象都共享每个实例方法的一个拷贝(实例方法只占用“一套”空间)。

静态方法和实例方法的访问权限表

静态成员变量
静态方法
实例成员变量
实例方法

静态方法
直接访问
直接访问
不可直接访问
不可直接访问

实例方法
直接访问
直接访问
直接访问
直接访问

总之:实例方法的存在必须要有对象实例的存在,如果对象实例不存在,则实例方法也就没有调用它的主人。静态方法的存在前提是类的存在,所以无需声明和New对象。

1.2代码演示 
class Program
{

    static void Main(string[] args)
    {
        Class1.CallObjectFunc();//静态调用

        Console.WriteLine(Environment.NewLine);

        Class1 tmpClass = new Class1();//实例调用
        tmpClass.ObjectFunc();

        Console.ReadKey();
    }
}

class Class1
{
    static int Class_m = 9;//静态成员
    private int object_m = 8;//实例成员

public static void CallObjectFunc()
    {
        Console.WriteLine("------------静态方法调用开始:");

        Class1 class1 = new Class1();
        class1.ObjectFunc();
        Console.WriteLine("object_m:" + class1.object_m.ToString());

        Console.WriteLine("------------静态方法调用结束:");
    }

    public void ObjectFunc()
    {
        Console.WriteLine("实例方法调用开始:");

        Console.WriteLine("Class_m:" + Class_m.ToString());

        Console.WriteLine("实例方法调用结束:");
    }
}

输出结果:

<span>【转载】C#扫盲之:静态成员、静态方法、静态类、实例成员及区别</span>

2.静态类

类可以声明为 static 的,以指示它仅包含静态成员。不能使用 new 关键字创建静态类的实例。例如,创建一组不操作实例数据并且不与代码中的特定对象关联的方法是很常见的要求。您应该使用静态类来包含那些方法。

静态类的主要功能如下:

  • 它们仅包含静态成员。—-函数成员和变量都必须有static修饰

  • 它们不能被实例化。

  • 它们是密封的。———–编译器编译时自动生成sealed标记

  • 它们不能包含实例构造函数。

因此创建静态类与创建仅包含静态成员和私有构造函数的类大致一样。私有构造函数阻止类被实例化。

使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员。编译器将保证不会创建此类的实利。

静态类是密封的,因此不可被继承。静态类不能包含构造函数,但仍可声明静态构造函数以分配初始值或设置某个静态状态。

静态类:

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
}
3.类的静态成员和非静态成员区别
    3.1区别

(1)语法区别:静态成员有关键字static,非静态成员无static修饰;

(2)存储区别:  静态成员变量存储位于程序的全局变量存储区,其作用域限制为类内部,并且在整个程序运行期间只在内存中拥有一个存储位置,不会拷贝不会复制,只是一个;

                      非静态成员变量存储位于对象的变量存储区,多个对象拥有多个变量的存储,只隶属于自己的的对象

(3)归属区别:静态成员隶属于类,是类的财产,无论对一个类创建多少个实例,它的静态成员都只有一个副本,在各个地方的改变都会改变其值;

                     非静态成员隶属于它的对象,各自对象同一个非静态成员值的改变都不互相影响,有多少实例就有多少副本;

(4)生存周期区别: 知道了存储位置的区别也就不难理解生存周期的差异了,静态成员只要分配了空间则在整个程序运行期间,它都是存在的,只有程序关闭之后,它的内存才会被GC回收器收回,不过作用域仍然只限制于类的内部,在类外部调用时需要使用类                                      名加点的方式访问;

                           类的非静态成员的生存周期跟随于隶属于对象的生存周期,对象消亡则非静态成员就会被回收;

(5)初始化顺序的区别:初始化都是最先初始化类的静态成员,然后才是非静态数据成员。

      3.2代码:

下面代码的输出是多少呢?先自己思考

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

class class1
{
    private static int i = getNum();
    private static int num = 1;

    int j = getNum();

    private static int getNum()
    {
        return num;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("i={0}", i);

        class1 class1Object = new class1();//默认构造函数
        Console.WriteLine("j={0}", class1Object.j);
        Console.WriteLine("i={0}", i);

        Console.ReadKey();
    }
}

输出结果为:

<span>【转载】C#扫盲之:静态成员、静态方法、静态类、实例成员及区别</span>

额,怎么回事这样呢?是不是会和你想的不一样,如果你真有这种想法,说明还需要看我下面的分析噢

代码分析

类结构:这个类有三个变量,两个私有静态成员变量i和num,一个非静态成员变量j;一个私有静态函数getNum(),一个函数入口Main()

程序执行过程:首先之前说了初始化会首先初始化类的静态变量。

i分配空间并初始化值为0–>num分配空间并初始化为0–>i赋值(调用getNum函数,此时num为0,返回值为0,所以i=0)–>num赋值为1–>Main函数

至于Main函数内执行时,为什么i输出不是1呢?这是因为静态成员只初始化一次,所以此时调用i并不会再调用getNum()函数为其赋值,此时的调用i是获取i分配空间上的值。

 

【转载】https://www.cnblogs.com/Matcha/p/5312268.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119348.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C++面试题之虚函数(表)实现机制

    C++面试题之虚函数(表)实现机制前言大家都应该知道C++的精髓是虚函数吧?虚函数带来的好处就是:可以定义一个基类的指针,其指向一个继承类,当通过基类的指针去调用函数时,可以在运行时决定该调用基类的函数还是继承类的函数.虚函数是实现多态(动态绑定)/接口函数的基础.可以说:没有虚函数,C++将变得一无是处!既然是C++的精髓,那么我们有必要了解一下她的实现方式吗?有必要!既然C++是从C语言的基础上发展而来…

    2022年7月13日
    13
  • EC20开发流程[通俗易懂]

    EC20开发流程[通俗易懂]EC20开发流程一、环境二、编译工具的使用三、准备工作四、编写代码五、烧录程序一、环境1、虚拟机ubuntu16.042、ql-ol-sdk对应的编译工具二、编译工具的使用1、将ql-ol-sdk.tar压缩包解压到虚拟机中的路径(最好是U盘挂载后,直接从U盘中解压过去),之后再在终端中ql-ol-sdk/ql-ol-crosstool$sourceql-ol-crosstool-e…

    2022年10月22日
    0
  • 一键锁定计算机快捷方式,还原win8系统创建一键锁定计算机的快捷方式的技巧…

    一键锁定计算机快捷方式,还原win8系统创建一键锁定计算机的快捷方式的技巧…今天和大家分享一下关于对win8系统创建一键锁定计算机的快捷方式设置的方法,在使用win8系统的过程中经常不知道如何去对win8系统创建一键锁定计算机的快捷方式进行设置,有什么好的办法去设置win8系统创建一键锁定计算机的快捷方式呢?在这里小编教你只需要1、首先在桌面上的空白处鼠标右击选择“新建–快捷方式”,然后在弹出来的创建快捷方式界面中,在“请键入对象的位置”框中输入:rundll32.ex…

    2022年7月21日
    14
  • 2020年云服务器采购季-福利专区

    2020年云服务器采购季

    2022年3月14日
    38
  • 性能和稳定性测试报告模板下载_产品稳定性报告怎样写

    性能和稳定性测试报告模板下载_产品稳定性报告怎样写目的:描述此次测试的目的:(以下目的请做参考)验证改进的性能效果,需要和以前的测试结果进行比对。新的业务上线,验证新系统能够满足系统的上线指标。验证系统稳定性验证系统的架构是否存在瓶颈测试环境:提供网络拓扑图可以使用visio来花图,描述清楚几个要点:几台测试服务器,每台都有什么服务,前台web服务、memcache、数据库?几台服务器的连接关系服务器软件信息说明: 服务器IP地址 服务器角色 数据库说明

    2022年9月8日
    0
  • eplan激活码分享-激活码分享

    (eplan激活码分享)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsaWNlbnNlSWQi…

    2022年3月21日
    1.6K

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号