关于后端:你也许还不懂静态方法和实例方法

2次阅读

共计 2207 个字符,预计需要花费 6 分钟才能阅读完成。

这两周没有妹子来找我问问题,有点小伤感,所以耽搁更新了。哈哈,别当真,因为菜菜这两周周末都有事(你能够认为去公司加班了),切实是没有精力,忘各位见谅!!

以下为菜菜本人观点,不代表任何妹子的观点, 请轻喷

面向对象

作为一个久经考验并失去业界必定的编程思维莫过于面向对象编程思维了。

面向对象 (Object Oriented,OO) 是软件开发办法。面向对象的概念和利用已超过了程序设计和软件开发,扩大到如数据库系统、交互式界面、利用构造、利用平台、分布式系统、网络管理构造、CAD 技术、人工智能等畛域。面向对象是一种对事实世界了解和形象的办法,是计算机编程技术倒退到肯定阶段后的产物。

谈到面向对象思维,首先你得有一个对象才能够。所以计算机蠢才在语言角度施展形象能力,在编程中把对象形象创立了进去,典型的代表作就是 java/c# 中的类(class)。把每一个 class 的类型看做事实世界中的一类对象,而后依据 class 能够创立进去多个 class 的实例,把这些实例看做是面向的具体对象。

为了完满的反对面向对象,大多数语言都反对了个性:封装,继承,多态。这也是诸多蛋疼的面试题中的常见题型。

利用场景

引入实例化办法概念是面向对象概念呈现当前的事件了,辨别静态方法和实例化办法不能单单从性能下来了解,创立 c ++,java,c# 这样面向对象语言的巨匠引入实例化办法肯定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化形式的辨别是为了解决模式的问题。

说的文言一点,到底是应用实例办法还是静态方法取决于业务的场景,当你的业务中每个对象都有本人的状态,或者行为,这些状态和行为是只属于以后对象的,那你的行为能够设计成实例办法。
举一个很简略的例子:一个游戏的我的项目中,每个玩家(player)都有本人的状态,比方玩家有一个行为:跳跃,不同的玩家跳的间隔可能不同,所以这个跳跃的行为体现到代码上就是一个 player 类型实例的办法。

至于静态方法,个别的定义成类型的行为和状态。因为类型是所有实例共享的,所以通常用作全局共享用处。理论我的项目中会发现有很多的 helper 类里边都是静态方法,因为这些办法和具体对象,和具体对象的行为状态没有任何关系。因为和具体实例没有连贯,所以这类型的静态方法简直都是线程平安的。
举个很简略的例子:我的项目中有很多加密的办法,这些办法的作用就是给一个参数,返回一个后果,没有任何本人的状态,所以这些办法被设计成静态方法。

在少数我的项目中,实例办法的使用量要大于静态方法,为什么呢?因为在少数零碎中充斥着各种对象的设计,各种 XX 设计模式的应用,而这些最终都应用了面向对象的思维。举一个最简略的 mvc 例子,无论是 java 中还是 c# 的 mvc 框架,controller 中的办法都是实例办法,因为每个 http 申请都有本人的状态,像 header 头信息,body 信息等,这些状态是属于以后 http 申请的,所以这些 controller 必须是实例办法才行。

简直古代所有的风行编程语言都提供了类型实例的继承和多态,通通都是为了更好的服务面向对象这个理念。为什么不提供类型的继承和多态呢?小伙伴们能够留言!

常见问题

静态方法是类型的办法,实例办法是每个实例的办法(每个语言模式不太一样):

 class Bird
    {
        // 静态方法
        static bool IsAnimal()
        {return true;}
        // 实例办法
        bool IsCanFly()
        {return true;}

    }
静态方法比实例办法快?

菜菜认为这是谬误的。一个办法的代码被加载到内存中,而后被 cpu 去执行,执行的速度快慢和是不是静态方法没有任何关系。然而有一个非凡的场景,那就是 GC。实例化太多对象在 java/c# 这类带有 GC 的编程语言中会引发垃圾回收操作,当垃圾回收进行的时候会挂起所有的线程,所以在这个短暂的工夫里,程序会卡顿。

静态方法常驻内存?

在一个类型第一次被应用的时候,会把静态方法和动态变量载入内存,直到过程被销毁。说道常驻内存,也算是一种误会,正确的说法是只有在被应用之后才会加载进入内存。当然在一些语言中能够手动卸载以后类型。

静态方法没有线程平安问题

菜菜认为是错的。有没有线程平安问题不是是不是动态所决定的,一个类型也能够有本人的状态和行为,只不过在一个过程中只有一份而已。当一个类型中的状态被多个线程批改的时候,就会有资源竞争问题,就会有线程平安问题。当一个类型的状态只有读的状况下,能够认为读这个办法是线程平安的。本人运行一下以下程序的后果

 class Program
    {static void Main(string[] args)
        {for (int i = 0; i < 20; i++)
            {Thread t = new Thread(() => {for (int i2 = 0; i2 < 100000; i2++)
                    {Add();
                    }
                   
                });
                t.Start();}
            // 为了模拟程序始终运行
            while (true)
            {Console.WriteLine($"Num 的值:"+Num);
                Thread.Sleep(1000);
            }

            Console.Read();}

        public static int Num;
        public static void Add()
        {Num= Num+1;}
    }

至于实例办法的线程平安问题,原理相似。有没有线程平安问题取决于状态有没有被多个线程并发批改,有没有资源竞争,和是否动态齐全没关系。

正文完
 0