通过案例了解静态修饰符static使用场景

  今天在csdn上看到一个关于static的帖子,里面的某个人的回复引起了我的注意。回复的大概意思是说:"面向对象里面的静态修饰是面向对象编程带来的垃圾产物,应尽量避免使用。"这句话大体能够体现static在大部分软件工程师眼里的尴尬地位,有一部分软件工程师除了在刚开始学习的时候,有使用过static外,就再也没有接触过static了。对此,我不得不说,这是一种遗憾。static是面向对象这个大家庭里面不可或缺的一员,少了它,面向对象的编程将少了许多的乐趣,多了许多烦扰。

  一、什么是static修饰符

  许多书和人都喜欢把static称之为静态,但我不喜欢这样称呼它,我更喜欢直接叫它static。因为我认为静态这两个字无法真正表达出static的真正作用。在程序中任何变量或者成员都是在编译时由系统自动分配内存来存储的,而用static修饰的成员会存储在一个static内存区中并且一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。那么这样的设计有什么意义了?在面向对象的概念中,这样的设计可是十分有意义的!因为这样的设计,static可以用来区分成员变量、方法是属于类本身还是属于类实例化后的对象。有static修饰的成员属于类本身,没有static修饰的成员属于类的实例。

  可能很多人还是不能理解,我在这边快速简单的写个例子吧。

class a{
  public $aa = 1;
  public function aa(){
    $this->aa += 1;
    echo $this->aa;
  }
}
class b{
  public function bb(){
    $aaa = new a();
    $aaa->aa();
  }
}
class c{
  public function cc(){
    $aaa = new a();
    $aaa->aa();
  }
}
$bbb = new b();
$ccc = new c();
$bbb->bb();
echo '*******************';
$ccc->cc();

注:在"this->aa"里面的"->"是php调用方法的方式类似于java里面的"."

上面代码很简单相信大家都能理解,我就不解释了。运行后的结果是2*******************2。

上面的代码是没用static的情况,下面我就再写一个用了static的demo。

class a{
  public static $aa = 1;
  public static function aa(){
    self::$aa += 1;
    echo self::$aa;
  }
}
class b{
  public function bb(){
    a::aa();
  }
}
class c{
  public function cc(){
    a::aa();
  }
}
$bbb = new b();
$ccc = new c();
$bbb->bb();
echo '*******************';
$ccc->cc();

注:"self::"和"::"是php中调用static修饰的成员的方式。里面的差异与本文要探讨的内容关系不大,咱不解释,有兴趣的可以自行研究。

最后的运行结果是2*******************3。这说明了,在static修饰下的成员变量$aa在第一次调用后并没有被释放,而是依然存在static内存块中,所有在第二次调用后输出的结果是3。因为第一次调用后的变量$aa从1变成了2,第二次调用的时候$aa还是2,所有二次调用后$aa变成了3。这就是static修饰的变量会一直存在的体现。同时,要记住在面向对象的编程中static修饰的成员不能直接调用非static修饰的成员。如果你知道了static的原理这个就很好理解了。拿java举例,用static修饰的成员,是专门存储在一个static内存区里面。非static修饰的成员是存储在堆内存里面。两者是分开存储的,所以要想在static修饰的成员里面调用非static修饰的成员,就必须跟在外面调用一样,先实例化,在调用。对于那为什么可以在非static修饰的成员里面直接调用static修饰的成员这个问题,我的解释是,你在类外面调用static成员时不也是可以不实例化类就直接调用吗?更何况在类里面了?

  虽然可以在非static修饰的成员里面直接调用static修饰的成员,但是我强烈建议大家不要这么做!原因后面会提到。

  二、什么时候使用static修饰符

  理解了上面说的,你只是初步了解了static,要想更近一步的理解static,就要读懂这句话:"static可以用来区分成员变量、方法是属于类本身还是属于类实例化后的对象。有static修饰的成员属于类本身,没有static修饰的成员属于类的实例。"很多初学者会搞不懂类和类的实例有什么不同?类是抽象的存在,而类的实例是类具体化的存在。两者是有区别的,因此就会发生一种情况,那就是有些类实例化后没有任何意义,也就是说没有实例化的必要,只有作为类才有意义。这时候,就必须用static来修饰成员变量和方法,表明这些变量和方法只属于类本身。比如:在做一个项目的时候,一个合格的软件工程师都会封装一个公共方法类,将经常用的公共方法放在里面,以便随时在项目中调用。这时候,你会发现,这个公共方法类,并没有一个合适的具体化的实例可以来表示,只有作为类的时候,才有其意义。所以里面的公共方法都可以用static来修饰,以表示这些方法都属于类本身,就不需要每一次使用一个公共方法的时候都要实例化出一个具体的对象了。还有就是像做安全防范(sql注入过滤、xss过滤等)的时候,将其统一封装成一个Security类,里面的方法就需要用到static来修饰,不然难道每一次过滤都要实例化一次吗?再开一个堆内存空间?类似的还有语言包、缓存等等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 对Django中static(静态)文件详解以及{% static %}标签的使用方法

    在一个网页中,不仅仅只有一个html骨架,还需要css样式文件,js执行文件以及一些图片等.因此在DTL中加载静态文件是一个必须要解决的问题.在DTL中,使用static标签来加载静态文件.要使用static标签,首先需要{% load static %}. 加载静态文件的步骤如下: 首先确保django.contrib.staticfiles已经添加到settings.INSTALLED_APPS中. 确保在settings.py中设置了STATIC_URL. 注意: 上面两条都是在创建Dja

  • 详解Vue-cli中的静态资源管理(src/assets和static/的区别)

    你可能注意到了我们的静态资源共有两个目录src/assets和static/,你们它们之间有怎样的区别呢? 资源打包 为了回答这个问题,我们需要了解webpack是如何处理静态资源的.在所有的*.vue文件中你所有的templates 和CSS 都被vue-html-loader 和css-loader 查询资源的URLs解析. 比如说, 在 img src="./logo.png" 和background: url(./logo.png) 中./logo.png是一个相对资源路径,并

  • .Net Core中间件之静态文件(StaticFiles)示例详解

    一.介绍 静态文件(static files),诸如 HTML.CSS.图片和 JavaScript 之类的资源会被 ASP.NET Core 应用直接提供给客户端. 在介绍静态文件中间件之前,先介绍 ContentRoot和WebRoot概念. ContentRoot:指web的项目的文件夹,包括bin和webroot文件夹. WebRoot:一般指ContentRoot路径下的wwwroot文件夹. 介绍这个两个概念是因为静态资源文件一般存放在WebRoot路径下,也就是wwwroot.下面

  • Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析

    本文实例讲述了Python 类方法和实例方法(@classmethod),静态方法(@staticmethod).分享给大家供大家参考,具体如下: demo.py(类方法,@classmethod): class Tool(object): # 使用赋值语句定义类属性,记录所有实例化工具对象的数量 count = 0 # @classmethod 定义类方法. 第一个参数是cls (cls用于访问类属性和类方法,不能访问实例属性/方法) @classmethod def show_tool_co

  • 如何配置vue.config.js 处理static文件夹下的静态文件

    最近开发过程中遇到个小需求,需要根据需求动态配置一些静态数据,但我不想直接把这个静态文件引入进来,build时就会把数据打包到js文件中,造成js文件很大:呃呃....(ps:就想给自己找点别扭) 回头看一下项目,果断的在根目录下创建一个static/test.json文件,在目标页面下fetch获取这个json文件里的数据: fetch("../static/test.json") .then(res => res.json()) .then(res => { //获取到

  • django中静态文件配置static的方法

    环境 centos7 django 1.11 nginx 白话 我们可以使用Template 设置我们的网页,同时,一个完美的网页需要css,js,image 等静态文件的支持. django中配置方式貌似有不少总,因为很多相关的博客写的方式并不一致,当然这可能是django 的版本不同导致的. 当我们在一个项目下创建一个app后,我们就需要为该app下创建一个static 文件夹来存放相关静态资源. 但创建了多个app后,就需要在多个app下创建static. 这样引入了一个问题,因为,我们的

  • 快速解决Django关闭Debug模式无法加载media图片与static静态文件

    开发时,通常打开Debug模式会快速定位开发时的一些问题. 项目开始部署时,关闭Debug模式,url.py路由静态文件和图片写法: # url.py from django.views import static from django.conf import settings #路由静态文件和图片 urlpatterns = [ url(r'^static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROO

  • PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解

    本文实例讲述了PHP中abstract(抽象).final(最终)和static(静态)原理与用法.分享给大家供大家参考,具体如下: abstract(抽象) PHP 5 支持抽象类和抽象方法.定义为抽象的类不能被实例化.任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现. 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法:另外,这些方法的访问控制必须和父类中一样(或者更为宽松).例

  • 通过案例了解静态修饰符static使用场景

    今天在csdn上看到一个关于static的帖子,里面的某个人的回复引起了我的注意.回复的大概意思是说:"面向对象里面的静态修饰是面向对象编程带来的垃圾产物,应尽量避免使用."这句话大体能够体现static在大部分软件工程师眼里的尴尬地位,有一部分软件工程师除了在刚开始学习的时候,有使用过static外,就再也没有接触过static了.对此,我不得不说,这是一种遗憾.static是面向对象这个大家庭里面不可或缺的一员,少了它,面向对象的编程将少了许多的乐趣,多了许多烦扰. 一.什么是st

  • 浅析php变量修饰符static的使用

    静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失.看看下面的例子: 复制代码 代码如下: function test(){static $a=0;$a++;echo $a;} test();//1test();//2test();//3Note: 静态变量可以按照上面的例子声明.如果在声明中用表达式的结果对其赋值会导致解析错误. 复制代码 代码如下: static $a=0+1;static $a=sqrt(121); 像上面的赋值方式会报错,不信你试试

  • TypeScript 类class与修饰符的详细使用教程

    目录 一.简介 二.成员修饰符 访问修饰符 只读修饰符 静态修饰符 总结 一.简介 通过 class 关键字定义一个类,然后通过 new 关键字可以方便的生产一个类的实例对象,这个生产对象的过程叫 实例化,类的成员就是类中所有的属性和方法. // 定义类 class Person { // 名称 name: string // 年龄 age: number // 构造函数 constructor(name: string, age: number) { // 更新熟悉数据 this.name =

  • C++中static修饰符的详解及其作用介绍

    目录 概述 静态数据成员 引用静态数据成员 用类名访问数据成员 静态成员函数 综合案例 概述 static (静态) 修饰符是用来控制变量的存储方式和可见性的. 静态局部变量存储在静态区域: static 的性质: 局部特性:作用范围仅限于本函数 静态特性:存储在静态区, 函数调用结束后不孝顺而保留原值. 在下一次调用时, 保留上一次调用结束时的值. 静态数据成员 在我们定义全局变量的时候, 我们会发现一个问题: 我们可以在程序各处自由的修改全局变量的值 (不安全). 静态数据成员的特点: 静态

  • Java修饰符abstract与static及final的精华总结

    目录 修饰符abstract (抽象的) 一.abstract可以修饰类 二.abstract可以修饰方法 修饰符之static? (静态的) 一.static可以修饰属性 二.static可以修饰方法 三.static可以修饰初始化代码块 修饰符之final? (最终的) 一.final可以修饰变量 二.final可以修饰方法 三.final可以修饰属性 修饰符abstract (抽象的) 一.abstract可以修饰类 (1) 被abstract修饰的类称为抽象类(2) 语法: abstra

  • Java开发必备的三大修饰符

    一.abstract 抽象的 抽象类:被abstract 修饰的类 语法: abstract class 类名{} 抽象方法 : 被abstract 修饰的方法 定义语法: 访问修饰符 abstract 返回值类型 方法名(参数列表): abstract 访问修饰符 返回值类型 方法名(参数列表): 特点: 1.当一个类中存在抽象方法 那么这个类也必须是抽象的 2.一个抽象类中可以有抽象方法也可以有非抽象方法 3.如果一个类继承了抽象类,这个类如果不想成为抽象类,那么这个类必须实现抽象类中的所有

  • 一篇文章带你入门Java修饰符

    目录 定义 分类 访问控制修饰符 非访问控制修饰符 修饰符的使用说明 修饰类 修饰方法 访问控制修饰符 非访问控制修饰符 修饰变量 总结 定义 Java修饰符:修饰符用来定义类.方法或者变量,通常放在语句的最前端. 分类 主要分为2类: 访问控制修饰符 非访问控制修饰符 访问控制修饰符 可以使用访问控制符来保护对类.变量.方法和构造方法的访问.分为以下4中权限:private,default,protected,public. 权限说明: 修饰符 当前类 同包 子类(不同包) 不同包(其他类)

  • java中的各种修饰符作用及范围

    目录 访问修饰符 作用范围 静态修饰符的特点 静态使用的注意事项 静态的优缺点 当成员变量被静态修饰后,和非静态成员变量的区别 访问修饰符 private 缺省 protected public 作用范围 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 不可以 不可以 缺省 可以 可以 不可以 不可以 protected 可以 可以 可以 不可以 public 可以 可以 可以 可以 private 被private修饰的属性和方法,

  • Java中的访问修饰符详细解析

    1.类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1 )公共类修饰符 public : Java 语言中类的可访问控制符只有一个: public 即公共的.每个 Java 程序的主类都必须是 public 类作为公共工具供其它类和程序使用的应定义为 public 类. 2 )抽象类修饰符 abstract :凡是用 abstract 修饰符修饰的类,被称为抽象类.所谓抽象类

  • c++中的static修饰符示例详解

    前言 本文主要给大家介绍了关于c++中static修饰符的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 下面一段是引用自effective c++ 中的一句话: 所谓的static对象,其寿命是从构造出来到程序结束为止(以下文章不再赘诉).因此stack和heap-base对象都被排除.这种对象包括global对象,定义于namespace作用域内的对象,在classes内,在函数内,以及在file作用域内被声明为static的对象. 所以static在c++中可以

随机推荐