day11_final, permission modifier, inner classes, reference types Summary

final keyword

Outline

After studying the inheritance, we know that a subclass can override the parent class content on the basis of the parent class, for example, the method of rewriting. Then we can inherit casual class API provided, rewrite its content? Obviously this is not appropriate. In order to avoid such arbitrary rewritten, Java provides a final keyword used to modify the contents can not be changed. final: immutable. It can be used to modify the class, method and variable.

Modified class

Format is as follows:

meaning:

  • This class does not currently have any subclass.

note:

  • If a class is final, then the method in which all the members can not be overwritten

For example:

Package demo01; 

/ * 
when used to modify a final keyword class, the format: 
public final class class name { 
    // ... 
} 

 * / 
public  final  class MyClass / * the extends Object * / {
     public  void Method () { 
        System.out.println ( "method performs!" ); 
    } 

}

Modification methods

Format is as follows:

Precautions:

  • For classes, methods, for, abstract and final keyword keyword can not be used because of contradictions.

meaning

  • When the final keyword when used to modify a method, this method is the final method, that can not be overwritten.

For example:

public  abstract  class Fu { 

    public  Final  void Method () { 
        System.out.println ( "parent method performed!" ); 
    } 

    public  abstract  / * Final * /  void methodAbs (); 

}

Modifying local variables

  • Modification of the basic types of local variables
Basic types of local variables, after being fifinal modified, can only be assigned once and can not be changed. code show as below:
Package demo01; 

public  class FinalDemo1 {
     public  static  void main (String [] args) {
         // declare variables, using the final modification 
        final  int A;
         // first assignment 
        A = 10 ;
         // second assignment a = 20; given, not reassign 

        // declare a variable, direct assignment, using final modification 
        final  int B = 10 ;
         // second assignment b = 20; given, not reassigned 
    } 
}
  • Modified reference type of local variables
Local variables of reference types, after being fifinal modified, can only point to an object, the address can not be changed. But it does not affect the internal value of the object's member variables to modify the code as follows:
Package demo01; 

public  class FinalDemo2 {
     public  static  void main (String [] args) {
         // Create User object 
        Final User = U new new User ();
         // Create another User object u = new User (); error, pointing new object, the value of the address change. 
        
        // call setName method 
        u.setName ( "John Doe"); // can be modified 
    } 
}

Modified member variable

For members of variables, if you use the keyword final modification, this variable is also still are immutable.

  • As the member variables have a default value, followed by the final must be manually assigned, the default value will not give up.
  • For the final member variable, using either direct assignment or assignment by the constructor. Both choose one.
  • Among the class constructor must ensure that all overloaded, all ultimately have the final member variable assignment.

Display initialization

public class User {
    final String USERNAME = "张三"; 
    private int age; 
}

Constructor to initialize

public class User {
    final String USERNAME;
    private int age;

    public User(String username, int age) {
        this.USERNAME = username;
        this.age = age;
    }
}

Permissions modifier

Outline

Offers four access in Java, using different access modifier modified, the modified content will have different access rights,
  • public: public.
  • protected: Protected
  • default: default
  • private: private

The ability to access different privileges

Visible, public has the greatest authority. private is the least privilege.

When you write code, if there is no special considerations, it is recommended to use this authority:

  • Member variables private, hidden details.
  • Constructor uses public, easy to create the object.
  • Members method uses public, easy to call the method.
小贴士:不加权限修饰符,其访问能力与default修饰符相同

内部类

什么是内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。

成员内部类

成员内部类 :定义在类中方法外的类。

定义格式:

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类 Car 中包含发动机类 Engine ,这时, Engine 就可以使用内部类来描述,定义在成员位置。

代码举例:

package demo02;


public class Body { // 外部类

    public class Heart { // 成员内部类

        // 内部类的方法
        public void beat() {
            System.out.println("心脏跳动:蹦蹦蹦!");
            System.out.println("我叫:" + name); // 正确写法!
        }

    }

    // 外部类的成员变量
    private String name;

    // 外部类的方法
    public void methodBody() {
        System.out.println("外部类的方法");
        new Heart().beat();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员。
  • 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象格式:

我们来使用上面的内部类对象

package demo02;


/*
如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。

分类:
1. 成员内部类
2. 局部内部类(包含匿名内部类)

成员内部类的定义格式:
修饰符 class 外部类名称 {
    修饰符 class 内部类名称 {
        // ...
    }
    // ...
}

注意:内用外,随意访问;外用内,需要内部类对象。

==========================
如何使用成员内部类?有两种方式:
1. 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
2. 直接方式,公式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
 */
public class Demo01InnerClass {

    public static void main(String[] args) {
        Body body = new Body(); // 外部类的对象
        // 通过外部类的对象,调用外部类的方法,里面间接在使用内部类Heart
        body.methodBody();
        System.out.println("=====================");

        // 按照公式写:
        Body.Heart heart = new Body().new Heart();
        heart.beat();
    }

}

代码执行后的结果

小知识:
  • 内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。比如,Person$Heart.class 

内部类的同名变量访问

package cn.itcast.day11.demo03;

// 如果出现了重名现象,那么格式是:外部类名称.this.外部类成员变量名
public class Outer {

    int num = 10; // 外部类的成员变量

    public class Inner /*extends Object*/ {

        int num = 20; // 内部类的成员变量

        public void methodInner() {
            int num = 30; // 内部类方法的局部变量
            System.out.println(num); // 局部变量,就近原则
            System.out.println(this.num); // 内部类的成员变量
            System.out.println(Outer.this.num); // 外部类的成员变量
        }

    }

}

局部内部类

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。

定义格式:

修饰符 class 外部类名称 {
  修饰符 返回值类型 外部类方法名称(参数列表) {
    class 局部内部类名称 {
      // ...
      }
    }
  }

定义一个类的时候,权限修饰符规则:

  • 外部类:public / (default)
  • 成员内部类:public / protected / (default) / private
  • 局部内部类:什么都不能写

举例:

class Outer {

    public void methodOuter() {
        class Inner { // 局部内部类
            int num = 10;
            public void methodInner() {
                System.out.println(num); // 10
            }
        }

        Inner inner = new Inner();
        inner.methodInner();
    }

}

局部内部类的final问题

局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是有效final的。从Java 8+开始,只要局部变量事实不变,那么final关键字可以省略。

原因:

  1. new出来的对象在堆内存当中。
  2. 局部变量是跟着方法走的,在栈内存当中。
  3. 方法运行结束之后,立刻出栈,局部变量就会立刻消失。
  4. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。
举例
public class MyOuter {

    public void methodOuter() {
        int num = 10; // 所在方法的局部变量

        class MyInner {
            public void methodInner() {
                System.out.println(num);
            }
        }
    }

}

匿名内部类

匿名内部类 :是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
  1. 定义子类
  2. 重写接口中的方法
  3. 创建子类对象
  4. 调用重写后的方法
我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。

前提

  • 匿名内部类必须继承一个父类或者实现一个父接口。
格式

对格式进行解析:

  • new代表创建对象的动作
  • 接口名称就是匿名内部类需要实现哪个接口
  • {...}这才是匿名内部类的内容

使用方式

以接口为例,匿名内部类的使用,代码如下:

定义接口:

package demo03;

public abstract class FlyAble {
    //定义抽象方法
    public abstract void fly();
}

创建匿名内部类,并调用:

package demo03;

public class InnerDemo {
    public static void main(String[] args) {
        /*
        1.等号右边:是匿名内部类,定义并创建该接口的子类对象
        2.等号左边:是多态赋值,接口类型引用指向子类对象
        */


        FlyAble f = new FlyAble() {
            public void fly() {
                System.out.println("我飞了~~~");
            }
        };
        //调用 fly方法,执行重写后的方法
        f.fly();//我飞了~~~
    }
}

通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:

package demo03;

public class InnerDemo1 {
    public static void main(String[] args) {
        /*
        创建匿名内部类,直接传递给showFly(FlyAble f)
          */
        showFly(new FlyAble() {
            public void fly() {
                System.out.println("我飞了~~~");
            }
        });
    }

    //通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。
    public static void showFly(FlyAble f) {
        f.fly();//我飞了~~~
    }
}

另外还要注意几点问题:

  • 匿名内部类,在【创建对象】的时候,只能使用唯一一次。如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
  • 匿名对象,在【调用方法】的时候,只能调用唯一一次。如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
  • 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】强调:匿名内部类和匿名对象不是一回事!!!

引用类型用法总结

实际的开发中,引用类型的使用非常重要,也是非常普遍的。我们可以在理解基本类型的使用方式基础上,进一步去掌握引用类型的使用方式。基本类型可以作为成员变量、作为方法的参数、作为方法的返回值,那么当然引用类型也是可以的。

class作为成员变量

  • 类作为成员变量时,对它进行赋值的操作,实际上,是赋给它该类的一个对象

interface作为成员变量

  • 接口作为成员变量时,对它进行赋值的操作,实际上,是赋给它该接口的一个子类对象。

interface作为方法参数和返回值类型

  • 接口作为参数时,传递它的子类对象。
  • 接口作为返回值类型时,返回它的子类对象

class作为方法参数和返回值类型

  • 类名作为参数,传递他的对象
  • 类名作为返回值,返回他的对象

抽象类作为方法参数和返回值类型

  • 抽象类作为参数,传递他的实现类对象
  • 抽象类作为返回值,返回他的实现类对象

Guess you like

Origin www.cnblogs.com/wurengen/p/12232899.html