在java中,为啥类实例也能访问静态域?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在java中,为啥类实例也能访问静态域?相关的知识,希望对你有一定的参考价值。

静态域中的除了静态块先执行一遍,静态变量或方法是为了共享只保存一个副本或者说状态,使用类名可以访问,使用实例名也可以访问,但是实例名会被编译时转换为类名,这算是是java的规则吧,不好说为什么 参考技术A 静态的成员变量或者方法、只是在类加载的时候就会被执行、当创建一个实例对象时、当然也能调用静态变量或方法了。 static的作用就只是让类加载的时候、静态代码块首先执行且只执行一次、、直到程序结束才会释放所占的内存、 这个跟实例变量访问有什么关系??

高级特性

  1. 静态方法和属性

    声明关键字  

      static

    作用域  

      静态方法以类为作用域,不能访问累的普通属性,但是允许访问静态属性,类的所有实例都允许访问静态属性(权限允许下)

    访问方式

      通过‘::’符号访问,当前类访问自己的静态属性和方法通过self关键字,类的实例不允许访问方法内部含有this关键字的静态方法

    作用

      它在代码中任何地方都能用(可以访问该类)

      类的每个实例都可以访问静态属性,利用静态属性来设置值,该值可以被所有类的实例使用

      不需要实例化就能访问静态属性和方法,不用为了获取一个简单的功能而实例化对象 

  2. 常量属性

    声明关键字  

      const NAME(常用大写字母命名)

    赋值范围

      只允许接收基本数据类型的值,不能讲对象指派给常量

    访问方式

      通过‘::’符号访问,与静态属性一样一般通过类而不是通过类的实例访问常量属性

  3. 抽象类

    声明关键字  

      abstract

    特点

      抽象类不能被直接实例化。抽象类只定义(或部分实现)子类需要的方法。子类可以继承它并通过实现其中的抽象方法,使抽象具体化

      抽象类也可以创建抽象类的方法和属性(属性不能声明为抽象 Properties cannot be declared abstract)

      大多数情况下,抽象类至少包含一个抽象方法,抽象方法abstract声明,不能有方法体

      抽象类的子类必须实现抽象类中的所有抽象方法,或者自身也声明为抽象方法,新的方法不能比抽象方法的访问控制更严格,参数个数一样

  4. 接口

    与抽象类的区别

      抽象类提供了具体实现的标准,二接口则是纯粹的模板

    声明关键字

      interface

    特点

      接口可以包含方法(没有方法体),但是不能有属性的声明(Interfaces may not include member variables)

      任何实现接口的类都要实现接口中所定义的所有方法,如果实现接口的类为abstract类,那么如果有些暂时不想实现方法体的方法必须声明为abstract方法

      一个类可以同时继承一个父类和实现多个接口

  5. 延迟静态绑定:static关键字
    <?php
    abstract class DomainObjetc{
        private $group;
        public function __construct(){
            $this->group=static::getGroup();
        }
        public static function create(){
            return new static();//指向被调用的类而不是包含的类
        }
    
        static function getGroup(){
            return "default";
        }
    }
    
    /**
    * 
    */
    class User extends DomainObjetc
    {
        
    }
    
    class Documwnt extends DomainObjetc
    {
        static function getGroup(){
            return "document";
        }
    }
    
    class SpreadSheet extends Documwnt
    {
        
    }
    
    print_r(User::create());//User Object ( [group:DomainObjetc:private] => default )
    print_r(SpreadSheet::create());//SpreadSheet Object ( [group:DomainObjetc:private] => document )
    ?>
  6. Final类和方法final关键字用来终止类的继承或者是方法的复写
  7. 拦截器

    __get($property)访问未定义的属性时被调用

    __set($property,$value)给未定义的属性赋值时被调用

    __isset($property)对未定义的属性调用isset()时被调用

    __call($method,$arg_array)调用未定义的方法时被调用

    <?php
    class test{
        public $age=18;
        public function __get($property){
            echo "你访问的未定义属性是:$property";
        }
    
        public function __set($property,$value){
            //$this->$property = $value;
            echo "你设置的未定义属性是:$property,值是$value";
        }
    
        public function __isset($property){
            echo "你isset判断的未定义属性是:$property";
        }
    
        public function __unset($property){
            echo "你unset的未定义属性是:$property";
        }
        public function __call($method,$arg){
            echo "你调用的未定义方法是:$method";
            print_r($arg);
        }
    }
    $a = new test();
    echo $a->age;//18
    $a->name;//你访问的未定义属性是:name
    $a->name=‘miake‘;//你设置的未定义属性是:name,值是miake
    isset($a->name);//你isset判断的未定义属性是:name
    unset($a->name);//你unset的未定义属性是:name
    $a->getAge(‘123‘,‘344‘,‘xxxxx‘);//你调用的未定义方法是:getAge  Array ( [0] => 123 [1] => 344 [2] => xxxxx )
    ?>

     

  8. _clone赋值对象

    php4,赋值对象只是简单的将一个变量赋值给另一个变量

    php5,对象的clone两个变量指向同一个对象的引用,而没有各自保留一份相同的副本

    <?php
    class acount{
        public $balance;
        function __construct($balance){
            $this->balance = $balance;
        }
    }
    /*
    浅复制可以保证所有基本数据类型的属性完全被复制
    而在复制对象属性时,只复制应用,并不复制应用的对象
    */
    class person{
        private $name;
        private $age;
        private $id;
        public $acount;
    
        public function __construct($name,$age,acount $acount)
        {
            $this->name = $name;
            $this->age = $age;
            $this->acount = $acount;
        }
        function setId($id){
            $this->id = $id;
        }
        function __clone(){//是在复制得到的对象上运行的
            $this->id = 0;
            $this->acount = clone $this->acount;
        }
    }
    
    $person1 = new person(‘bob‘,44,new acount(200));
    $person1->setId(343);
    $person2 = clone $person1;
    //
    $person1->acount->balance+=10;
    
    print_r($person1->acount->balance);//210
    print_r($person2->acount->balance);//200
    
    ?>

     

  9. _tostring
    <?php
    class test{
        function getName()
        {
            return ‘hello‘;
        }
    
        function getAge(){
            return 18;
        }
    
        function __tostring(){
            $des = get_class();
            $args = get_class_methods($des);
            foreach ($args as $method) {
                $des.=‘method:‘.$method.‘<br>‘;
            }
            
            return $des;
        }
    
    }
    $a = new test();
    print($a);
    /*
    testmethod:getName
    method:getAge
    method:__tostring
    */
    ?>
  10. 回调、匿名和闭包
    <?php
    class Product{
        public $name;
        public $price;
        function __construct($name,$price)
        {
            $this->name = $name;
            $this->price = $price;
        }
    }
    
    class processing{
    
        private $callback;
    
        public function registerCallback($callback){
            if(!is_callable($callback)){//
                throw new Exception("callback not callble", 1);
            }
            $this->callback[] = $callback;
        }
    
        public function sale(Product $Product){
            echo "{$Product->name}:processing\n";
            foreach ($this->callback as $callback){
                call_user_func($callback,$Product);
            }
        }
    }
    
    class Totailzer{
        static function warnAmount($amt){
            $count = 0;
            return function($Product) use($amt,&$count){
                $count+=$Product->price;
                echo "  count:$count\n";
                if($count>$amt) {
                    echo "  hignt price reached:{$count}\n";
                }
            };
        }
    
    }
    
    $processer = new processing();
    //回调函数
    /*$logger = function($Product){
        echo "  loging{$Product->name}";
    }*/
    $processer->registerCallback(Totailzer::warnAmount(8));
    $processer->sale(new Product(‘shoes‘,6));
    $processer->sale(new Product(‘coffee‘,6));
    
    ?>

 

以上是关于在java中,为啥类实例也能访问静态域?的主要内容,如果未能解决你的问题,请参考以下文章

Python中静态方法和类方法的区别

Java中的作用域有哪些

java静态方法和实例方法的区别

java对象与类

面向对象中静态方法和属性的理解

为啥 C# 公共静态变量不需要实例化?