面向对象(五)

面向对象

07.08


理解访问修饰符 (信息隐藏)

被访问被调用的范围
- public :全部
- 默认 :同包
- protected :同包或有继承关系的类
- private :只有同类

在A类中定义属性和方法:

  • public:这个类的实例化对象可以访问;
  • 默认: 如果在同包下定义一个主类,然后在主类的主方法里面new A的一个对象出来,则这个对象可以访问被默认修饰的属性和方法;
  • protected:在同一个包下的类中new的A类对象和继承了A类的相同或不同包下的子类中new A类对象,这个对象能调用A类中所有的属性和方法(不同包下没有继承关系的类不能访问)
  • private:只有这个类中的属性和成员方法能访问

geter和setter更深入理解

  • 当把类的属性和方法访问权限设置为private时,一般都提供上面2个公共方法;
    在这2个方法体内,可以添加一些限制代码;
    比如说setter方法,需要用户输入账号密码才有权限修改
    getter也可以这么做,还可以在返回值的时候做一些动作;
    这就是隐藏.
  • 也可以用private修饰setter方法,那么这个属性就是只读;
  • 用private修饰getter方法,这个属性就是只写;

封装的好处

  1. 类的成员变量可以成为只读或只写
  2. 类可以对存储在其成员变量中的内容有一个整体的控制
  3. 类的用户不需要知道类是如何存储数据的

static关键字 (类级别的,与对象无关)

  1. static修饰的全局变量叫静态变量,也叫类变量,被所有的对象所共享,用类名.属性访问;
  2. static修饰的方法叫静态方法,即类方法;可以直接用类名.方法访问;
  3. 类只能使用类方法,而不能使用静态变量;
  4. 类加载以后就存在内存中了,在mian方法执行之前;
  5. 用static修饰的变量存在堆内存的数据段的静态区中

public static final int MAX = 100;

常量属性定义为static,节约空间
final:因为用final修饰,所以是个常量
public:因为是常量,所以不能更改,public修饰给别人看也没事
static:共享,这样就不用new出来才能使用;

  • 静态方法只能访问或调用静态属性和静态方法
  • 非静态方法法既能访问调用非静态属性和方法,也能访问静态方法和属性
    原因:静态属性和方法在类加载的时候就加载到内存中了,而非静态属性和方法必须绑定在对象上,而对象必须先实例化才能调用;
    如果用静态方法访问非静态属性,但是内存中却不存在非静态属性,所以编译器会报错.

代码块

静态初始化块

  • 语法:static {语句1;语句2;…;};
  • 调用顺序:当类被JVM的类加载器加载的时候执行,
    只加载一次,因为JVM只加载一次类.

实例化初始化块

  • 语法:{语句1;语句2;…;};
  • 调用顺序:在类的对象每次实例化的时候执行一次,在构造器之前调用;
class A {
    public String name = "成员属性" ;
    static {
        System.out.println("静态初始化块");
    }

    {
        this.name = "name";
        this.age  = 26;
        System.out.println("实例初始化块内");
        System.out.println(this.name);
        System.out.println(this.age);
    }
    public int age = 10;

    public A ( ) {
        System.out.println("构造方法内");
        System.out.println(name);
        System.out.println(age);
    }
}
//主方法 
class ClassName {
    public static void main(String[] args) {
        new A();
    }
}

输出结果 :
静态初始化块
实例初始化块
name
26
构造方法内
name
10

步骤:
1. 执行到new A();时,加载A.class到内存中;
2. static随着类的加载而创建(在堆内存的数据段中的静态区中,存放的是静态变量和静态方法,常量存放在堆内存的数据段的常量池中)
3. 输出 静态初始化代码块
4. 执行构造方法时要做的事:

  • 在堆内存中申请内存;(size = int + String)
  • 分配这块内存;(给name分配4字节空间,因为它是一个引用;给age分配4个字节);
  • 初始化这块内存中的变量,name="成员属性";age=10;
  • 调用实例初始化代码块,执行代码块中的语句 name = name,age=26;
  • 执行实例代码块后面的语句;public int age = 10;
  • 执行构造方法内的语句 输出nameage的值;

内部类 (先大概了解)

  • 在类的里面再定义一个类,这个类就叫内部类;
  • 它是一个独立的类;
  • 可以产生对象使用;
  • 编译后又独立的class文件;
    • classA$1classB –>是局部内部类;(比成员内部类少了一个数字,因为一个类有多个方法,在不同的方法里面可以定义相同名字的内部类,为了区分,编译器自动为我们添加你一个数字作为区分)
    • classA$classB –>是成员内部类;(把成员内部类作为外部类的属性,属性当然不能重名了,所以成员内部类的名字不能相同)

分类

  • 成员内部类 –>定义在外部类中方法外面的类;
    • 静态内部类:(成员内部类的一种)
  • 局部内部类 –>定义在外部类的方法里面,定义的时候不能加访问修饰符
    • 匿名内部类:没名字,主要用于实现接口的方法.

为什么局部内部类不能用访问修饰符修饰?

从内存中看,当方法里的局部变量所在方法结束时,该变量即在栈内存中消失;而内部类其实是一个类,只有内存中对它的所有引用都消失后,该内部类才”死亡”,即内部类的生命周期可能比局部变量长。如果局部内部类能访问一般的局部变量,则在多线程中,可能当方法结束后,局部内部类(是线程类时)还在使用局部变量。为了避免方法内的变量脱离方法而存在的现象发生,于是java规定局部内部类不能访问一般的局部变量。但能访问被final修饰的局部变量。因为常量放在堆内存中的数据段的常量池中


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值