zoukankan      html  css  js  c++  java
  • 疯狂java学习笔记之面向对象(八)

    一、static:

      1、static是一个标识符

        - 有static修饰的成员表明该成员是属于类的;

        - 没有static修饰的成员表明该成员是属于实例/对象的。

      2、static修饰的成员(Field、方法、初始化块),与类共存亡;static修饰的成员建议总是通过类名来访问,虽然它也可以通过实例来访问(实质也是通过类来访问的),所以平时若在其他程序中见到通过实例/对象来访问static成员时,可以直接将实例/对象 替换成类名;

      3、程序都是先有类再有对象的,有可能出现有类但没有实例/对象的情况,反过来绝对不可能出现有实例/对象却没有类的现象。

      4、类加载时会把属于类的Field存放到永生代堆内存中。

      规则:

      A、static修饰的成员不允许访问非static成员,非static成员可以访问static成员;

      B、this引用、super都丕允许出现在static成员中;

      C、若Field是实例/对象的,相当于前面省略了this.  , 若Field是类的则相当于前面省略了类名.

    注意点:若自己写程序永远都不要使用对象/实例去调用static修饰的方法、Field,若看到其他程序出现实例/对象去调用static修饰的方法、Field,我们阅读时则先把对象换成类名.

     1 public class TestStatic{
     2     private int age;
     3     private String name;
     4     private static String gender;
     5     private double weight;
     6 
     7     public void test(String name){
     8         System.out.println("他/她叫: " + name);
     9     }
    10 
    11     public static void main(String[] args){
    12         TestStatic ts = new TestStatic();
    13         ts.test("小猴子");
    14         //通过对象ts来访问static成员,可以替换成类名.gender
    15         //因为gender是string引用变量且属于成员变量,若程序员没给它赋初始值,系统会默认给个null值它
    16         System.out.println(ts.gender);
    17         System.out.println(TestStatic.gender);
    18     }
    19 }
     1 public class TestStatic2{
     2     static int count = 99;
     3     int age;
     4     {
     5         age = 22;
     6         test();
     7     }
     8 
     9     static{
    10         test();
    11         //age = 13; //static成员不能访问非static成员
    12     }
    13 
    14     public void way(){
    15         System.out.println("age值为: " + age);
    16     }
    17 
    18     public static void test(){
    19         //static方法引用了非static修饰的age,报错
    20         //System.out.println("age的值为: " + age);
    21         System.out.println("~~这是一个test方法~~");
    22     }
    23 
    24     public static void main(String[] args){
    25         //定义了一个t2引用变量但t2并未指向任何对象
    26         TestStatic2 t2 = null;
    27         TestStatic2 t3 = new TestStatic2();
    28         //对于static修饰的Field、方法,直接打印时相当于前面省略了类名
    29         System.out.println(count);  //t2.count
    30         //成员变量前必须有主调对象且有static修饰的方法不能直接访问没有static修饰的变量
    31         System.out.println(t3.age);    //t3.age;
    32     }
    33 }

    二、final:

      final作为一个修饰符,只能修饰:变量、方法和类

      1、final修饰变量

        --final修饰的变量只能被赋值一次且赋值后不可改变

       A、final修饰成员变量

        Java成员变量默认可以由系统执行初始化,程序员可以不指定初始化,但final修饰的成员变量必须由程序员执行初始化

        [原因]:如果final修饰的成员变量由系统执行初始化,那它的值只能是0、0.0、null、false、u0000,且还不能改变,那么该变量则会变得毫无价值

        若final修饰【实例变量】,可以在以下3个地方指定初始值:

         ①、定义时指定初始值;

         ②、初始化块中指定初始值;

         ③、构造器中指定初始值。 

        注意:final修饰的变量只能指定一次初始值且普通方法是不允许为final实例变量赋值的。

     1 public class TestFinal{
     2     //final修饰实例变量必须指定初始值且只能在定义时、初始化块、构造器中指定。
     3     final int age = 20;
     4     final double weight;
     5     /*
     6     {final修饰的变量只能被赋值一次。
     7         weight = 150;
     8     }*/
     9 
    10     {
    11         System.out.println("~~实例初始化块~~");
    12     }
    13 
    14     public TestFinal(){
    15         weight = 140;
    16     }
    17 
    18     /* 普通方法不能为final修饰的变量赋值
    19     public void setWeight(){
    20         this.weight = weight;
    21     }*/
    22     
    23     public static void main(String[] args){
    24         TestFinal tf = new TestFinal();
    25         //实例变量必须拥有主调者
    26         System.out.println(tf.weight);
    27     }
    28 }

        若final修饰【类变量】,只可以在以下两个地方指定初始值:

         ①、定义时指定初始值;

         ②、类初始化块中指定初始值。

       B、final修饰局部变量:

        Java的局部变量默认就必须由程序员来指定初始值

        final修饰局部变量后,只有【一个变化】:一旦赋值后就不能再改变了。

     1 public class TestFinal3{
     2     public static void main(String[] args){
     3         final int age;
     4         age = 12;
     5         System.out.println(age);
     6         //final修饰age后,age只能赋值一次,否则报错"可能已分配变量age"
     7         //age = 22;
     8         //System.out.println(age);
     9     }
    10 }

       C、final修饰的变量,它会被执行“宏替换”。如果final修饰的变量,可以【在编译的时候就确定】它的值,那么这个【变量就不存在】“宏替换” -- 就是查找、替换

     1 public class  FinalConstant {
     2     public static void main(String[] args) {
     3         String s1  =  new String("疯狂java");
     4         String s2  =  new String("疯狂java");
     5         System.out.println(s1  ==  s2);  //false
     6 
     7         //JVM会把所有用过的String对象进行缓存
     8         String s3  =  "fkjava.org";
     9         String s4  =  "fkjava.org";//第二次用的是缓存中的fkjava.org对象
    10         System.out.println(s3  ==  s4);  //true
    11 
    12         //由于+前后的值都是"直接量",可以直接计算
    13         String s5  =  "疯狂"  +  "软件";
    14         //在编译的时候,编译器已经把"+运算"计算出来,由于+前后的值都是"直接量",可直        //接计算
    15         String s6  =  "疯狂软件"    ;//JVM在编译时就自动去掉+号
    16         //s5、s6两个引用变量是否相等【必须指向同一个对象才相等】。
    17         System.out.println(s6  ==  s5);  //true
    18 
    19         String s7  =  "疯狂";
    20         String s8  =  "java";
    21         //由于s7、s8都是变量,他们的值只有在运行时才能确定下来
    22         //因此s9、s10的值只能在运行是动态的确定,都不会缓存,因此无法直接使用缓存中的值
    23         String s9  =  s7  +  s8;
    24         String s10  =  s7  +  s8;
    25         System.out.println(s9  ==  s10);
    26 
    27         /*
    28         final String s11 = "fkjava";
    29         final String s12 = ".org";
    30         String s13 = s11 + s12;
    31         String s14 = s11 + s12;
    32         System.out.println(s13 == s14);  //true */
    33 
    34         // final修饰的变量,【声明时就指定了初始值】,但他们的初始值在编译时不能确定,        //所以不能执行宏替换,所以s11、s12只有在运行时才能确定
    35         final String s11 = s9; //s11的字符序列是:疯狂java
    36         final String s12 = s10;//s12的字符序列是:疯狂java
    37         String s13 = s11 + s12;
    38         String s14 = s11 + s12;
    39         System.out.println(s13 == s14);  //false
    40 
    41         //final修饰的变量,【声明时就指定了初始值】,【而且初始值在编译就可以确定】
    42         //那么这个变量就不存在,s15/s16会执行“宏替换”,也就是这两个变量根本就不存        //在,所有出现s15的地方都会替换成"fkjava",s16替换成".org"
    43         //final String s15 = "fkjava"; 
    44         //final String s16 = ".org";
    45         /*String s17 = s15 + s16;
    46         String s18 = s15 + s16;*/
    47 
    48         String s17 = "fkjava" + ".org";
    49         String s18 = "fkjava" + ".org";
    50         System.out.println(s17  ==  s18);  //true
    51 
    52     }
    53 }

      3、final修饰方法:

       final修饰的方法不能被重写@Override;

       好处:禁止父类的方法被重写,避免破坏父类方法

       注意点:final与private结合没有实际意义,两者存一即可(private本身就不能被重写)。

      4、final修饰类:

       final类不能有子类,由于它不能有子类,所以它的方法能可以被更好的保护,典型的final类有:String、System、Math和包装类。

  • 相关阅读:
    Linux环境下搭建Git仓库
    Linux环境下安装zookeeper
    nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
    Dart语言特性必备了解!
    Flutter中打造多行列列表GridView组件的使用
    Flutter常用组件(Widget)解析-Scaffold
    Flutter常用组件(Widget)解析-ListView
    Flutter常用组件(Widget)解析-Image
    Flutter常用组件(Widget)解析-Text
    Flutter常用组件(Widget)解析-Container
  • 原文地址:https://www.cnblogs.com/dtest/p/4176305.html
Copyright © 2011-2022 走看看