目录

类的封装

1.为什么要进行封装

2.如何实现封装

this关键字

1.解决成员变量和局部变量名冲突的问题

2.通过this调用成员方法

3.通过this调用构造方法

构造方法

构造方法的定义

构造方法的重载

代码块

静态代码块

实例代码块


Java中,针对类,成员方法和属性提供了四种访问级别private,default,protected,public

java实现封装的jar文件不可被反编译_System

  •  private(当前类访问级别),如果说一个类的成员被private修饰,则这个成员只能被该类的其他成员访问,而其他类无法直接访问
  • default(包访问级别),如果说一个类或者类的成员不使用任何控制符修饰,则称他为默认访问级别,这个类或者类的成员只能被本包的其他类访问
  • protected(子类访问级别)如果一个类的成员被protected修饰,那么这个成员既可以被同一包下的其他类访问,也可以被其他包下的该类的子类访问
  • public(公共访问级别)如果说一个类或者类的成员使用public修饰,那么这个类或者类的成员可以被所有的类访问,不管访问类和被访问类是不是在同一个包里

类的封装

1.为什么要进行封装

封装:属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限

封装的意义是:尽量避免向外部暴露实现细节,只提供个别接口让使用方调用。这样做的话,当自身的逻辑发生变化时,不会破坏使用方的逻辑,或是强制使用方修改自身的逻辑,而是只需要修改自身的代码就可以了

封装的本质是将事物相关的属性和方法封装在一个类里面,我们调用类创建实例的时候,不用关心类内部的代码细节,相当于一个黑箱子,我们只需要该实例(黑箱)能给出我们想要的结果就好了。

2.如何实现封装

定义一个类时,将类中的属性私有化,私有属性只能在它所在的类中被访问,如果说外部想要访问该属性,则需要提供一些公有方法

class Print{
    private int age;
    private String name;
    public int fun() {
        age=9;
        return age;
        //private修饰,age只能在定义age的类中使用,别的类使用,需要借用公开方法
    }
}
public class texe {
    public static void main(String[] args) {
        Print p=new Print();
        //System.out.println(p.age);
        //private修饰,age只能在定义age的类中使用,别的类使用,需要借用公开方法
        System.out.println(p.fun());
    }
}

this关键字

1.解决成员变量和局部变量名冲突的问题

class  Sout{
        int age=8;//成员变量
        public void print(int age) {//age是局部变量,形参9
            age = age;//当局部变量和成员变量同名时,局部变量优先于全局变量
            //9=9 成员变量仍是8

           this. age = age;//this引用了成员变量
            // 成员变量更改为9
        }
}
public class texe {
    public static void main(String[] args) {
      Sout p=new Sout();
      p.print(9);
        System.out.println(p.age);
    }

2.通过this调用成员方法

class Person {
    int age=0;
    public void print(int age){
        this.age=age;
        System.out.println(this.age);
    }
    public void speak(int age){
        this.print(2);
    }
}
class text {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.speak(3);
    }
}

main方法中调用speak方法,speak方法内调用print()成员方法,print()方法中,this.age调用成员变量,成员变量改为形参2的值

3.通过this调用构造方法

构造方法是在实例化对象时被自动调用的,在程序中不可以像调用普通方法那样调用构造方法,但是可以使用this在一个构造方法中调用其他的构造方法

class Person {
  public  Person(){
      this(2);
      System.out.println("这是一个没有参数的构造方法");
    }
    public  Person(int age){
        System.out.println("这是一个有参数的构造方法"+"传入形参="+age);
    }

}
class text {
    public static void main(String[] args) {
        Person p1 = new Person();
    }
}

在创建对象时,自动调用了无参数的构造方法,先执行this(2),调用了有参数的构造方法

java实现封装的jar文件不可被反编译_封装_02

注意事项:

1.只可以在构造方法中使用this调用其他构造函数,而不可以在成员方法中调用

class Person {
    public void print(){//成员方法
        this();//成员方法不能使用this调用构造方法
        System.out.println("ok");
    }
  public Person(){//构造方法
      System.out.println("hi");
  }
    public Person(int age){构造方法
        System.out.println("hello");
    }
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
    }
}

2.构造方法中,this必须是第一条语句,且只能出现一次

class Person {
  public Person(){
      System.out.println("hi");
      this(10);
  }
    public Person(int age){
        System.out.println("hello");
    }
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
    }
}
class Person {
  public Person(){
      this(10);
      System.out.println("hi");
      this(20);
  }
    public Person(int age){
        System.out.println("hello");
    }
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
    }
}

java实现封装的jar文件不可被反编译_封装_03

3不能在一个类中的两个构造方法互相使用this调用

class Person {
  public Person(){
      this(10);
      System.out.println("hi");
  }
    public Person(int age){
      this();
        System.out.println("hello");
    }
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
    }
}

java实现封装的jar文件不可被反编译_构造方法_04

构造方法

构造方法的定义

如果说需要在实例化对象的同时就为这个对象的属性进行赋值,可以使用构造方法来实现。

构造方法是类的一个特殊成员,它会在类实例化对象时被自动调用。

构造方法的定义

【修饰符】方法名(方法参数){

方法体

}

要求:

  • 方法名和类名相同
  • 方法名的前面没有返回类型
  • 不能使用return返回一个值,但是可以单独写return语句来结束方法
class Person{
        int age;
        public Person (){
            System.out.println("这是个构造方法");
        }
}
class text {
    public static void main(String[] args) {
    Person p=new Person();
    }
}

在这个代码中,会打印:这是个构造方法

 在Person这个类中,定义了一个无参数的构造方法 Person,执行Person p=new Person();创建Person对象时会自动调用构造方法

构造方法的重载

构造方法之间也可以构成重载

class Person{
        int age;
        public Person (){
            System.out.println("这是个构造方法");
        }
    public Person (int s){
        System.out.println("这是个有参数构造方法"+s);
    }
}
class text {
    public static void main(String[] args) {
        Person p = new Person();
        Person p1 = new Person(3);
    }
}

java的每一个类中至少会有一个构造方法:如果说在一个类中没有定义构造方法,系统会自动地为这个类创建一个默认的构造方法,这个默认的构造方法没有参数,方法体中也没有任何代码。一旦为该类定义了构造方法,系统将不会提供默认的无参数构造方法

class Person{
        int age;
    public Person (int s){
        System.out.println("这是个有参数构造方法"+s);
    }
}
class text {
    public static void main(String[] args) {
        Person p1 = new Person(3);
        Person p = new Person();
    }
}

java实现封装的jar文件不可被反编译_java_05

原因: Person类中已经创建了有参数的构造方法,这时,系统不会提供默认的无参数构造方法。所以:如果说一个类里面如果已经定义了有参数的构造方法,那么最好再定义一个无参数的构造方法

class Person{
        int age;
    public Person (int s){
        System.out.println("这是个有参数构造方法"+s);
    }
    public Person (){
        System.out.println("这是个有参数构造方法");
    }
}
class text {
    public static void main(String[] args) {
        Person p1 = new Person(3);
        Person p = new Person();
    }
}

代码块

在java类中,{ }括起来的若干行代码被统称为代码块

静态代码块

被static修饰的代码块称之为静态代码块

实例代码块

class Person {
    public  Person(){
        System.out.println("这是一个没有参数的构造方法");
    }
   {
        System.out.println("这是一个实例代码块");
    }
    static{
        System.out.println("这是一个静态代码块");
    }
    
}
class text {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println("==============");
        Person p = new Person();
    }
}

java实现封装的jar文件不可被反编译_System_06

class Person {
    static void print(){
        System.out.println("这是一个没有参数的构造方法");
    }
   static {
        System.out.println("这是一个静态代码块");
    }
    {
        System.out.println("这是一个实例代码块");
    }
}
class text {
    public static void main(String[] args) {
      Person.print();
    }
}

java实现封装的jar文件不可被反编译_构造方法_07

结论:静态代码块就算不实例化对象,都会被加载,且只会被加载一次。

加载一个类,先会加载类里面的静态代码块,其次是实例代码块,后是其他方法(和相对位置无关)

但是,如果都是静态变量/都是全局变量,和相对位置有关

class Person {
    public static int age = 20;
    static {
        age = 10;
    }
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
        System.out.println(p.age);
    }
}

结果:10,即先执行  public static int age = 20;

class Person {
    static {
        age = 10;
    }
    public static int age = 20;
}
class text {
    public static void main(String[] args) {
        Person p=new Person();
        System.out.println(p.age);
    }
}

结果:20,即后执行  public static int age = 20;

但是,有一种特殊情况,当不初始化时,结果和相对顺序无关

class Person {
    static {
        age =5;
    }
    public static int age ;
}
class Person {
    public static int age ;
    static {
        age =5;
    }
}

结果都是5