带你深入理解面向对象三大特性 - 封装

目录

前言:

访问权限:

public

private

protected

默认权限

示例:

 static成员:

static修饰成员变量

static修饰成员方法

static成员变量初始化

就地初始化

代码块:

普通代码块

构造代码块

静态代码块 

内部类:

实例内部类

静态内部类

局部内部类

 续:构造成员方法

小结:


前言:

    在现实生活中,我们每一个个体都是作为对象而存在的,而我们需要用代码将这些复杂的对象描绘出来,那么就需要我们站在编程的思想上去理解。在用类实例化对象时,有一些成员属性或者成员变量我们是不希望被外界直接访问的,但同时会提供一些公共的接口,来支持对它们的一些操作。

    在Java中主要通过类和访问权限修饰符来体现出封装的特性,类可以将数据以及封装数据的方法结合在一起,访问权限用来控制方法或者字段能否直接在类外使用。

访问权限:

public

🎈同一包中同一类或者不同类,不同包中的子类或者非子类都可以访问。

private

🎈只能在本类内进行访问。

protected

🎈同一包中同一类,或者不同类,不同包中的子类可以访问。

默认权限

🎈什么修饰符都不写,又称为包访问权限,同一包中同一类或者不同类可以访问。

示例:(一般成员属性用private修饰,成员变量用public修饰)

class Person{
    private int age;
    private String name;
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Test1 {
    public static void main(String[] args) {
        Person stu = new Person();
        stu.setAge(21);
        stu.setName("aaaa");
        System.out.println(stu.getName() + stu.getAge());
    }
}

可以清楚的看见类中对私有成员提供了一些方法来设置和获取它。

Person stu = new Person();

😯这句代码就是用Person类来实例化stu这个对象,stu是局部变量存储在栈区,new是在堆区申请的一块空间,stu存储这块空间的地址,指向这块空间。可以看见Person后有一对括号,这个实际上是调用了构造成员方法,调用构造成员方法是实例化对象的必要条件,它是支持重载的。后面详细讲解。

 static成员:

在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

static修饰成员变量

class W{
    static int a = 10;
}
public class Test2 {
    public static void main(String[] args) {
        W p1 = new W();
        System.out.println(W.a);
        System.out.println(p1.a);
    }
}

🐵被static修饰的成员变量不属于某一个对象,它属于整个类,是所有对象共享的。所以可以通过类名去访问静态成员变量,虽然也可以通过对象去访问,但一般都是用类名去访问的。

🐵它的生命周期随类的加载就形成了,类的卸载而销毁

🐵它存储在JVM中的方法区

注意:局部变量是不可以被static修饰的。

static修饰成员方法

class W{
    private int a;
    private static int b;
    public void fun2(){
        System.out.println("aaaa");
    }
    public static void fun(){
        b = 20;
        W p1 = new W();
        p1.a = 10;
        p1.fun2();
    }
}
public class Test2 {
    public static void main(String[] args) {
        W p1 = new W();
        W.fun();
        p1.fun();
    }
}

🪖与static修饰成员变量的作用区域一致,也是属于整个类,不属于某一个对象。

🪖可以对象引用的方法去调用,但一般用类名去调用。

🪖在static修饰的成员方法内,只能直接访问静态成员属性

🪖由于非静态成员属性是属于某一个类的,和静态成员方法相比,本质上是不同的,所以需要对象的引用方法去访问。

🪖静态方法中不可以直接调用非静态成员方法,由于非静态成员方法中存在对象的引用this参数,而静态成员方法属于整个类不存在this。只有通过对象引用的方法去调用。

static成员变量初始化

注意:静态成员变量初始化一般不通过构造方法来完成,构造方法中初始化的是与对象相关的实例属性。

就地初始化

public class Test3 {
    private static int a = 10;
}

🎄定义时直接在后面赋初值,由于它属于整个类,用这个类实例化出的对象访问的都是同一个a。

🎄静态代码块也可以初始化静态成员变量。

代码块

普通代码块

public class Test3 {
    private int a;
    public void fun(){
        int b = 10;
        {
            int c = 10;
        }
    }
}

💎定义在方法内部,c就是一般的局部变量,作用域也就在这个括号的区域里。

构造代码块

public class Test3 {
    private int a;
    {
        a = 20;
    }
}

🧢定义在类中的代码块(不加任何修饰符),一般用于初始化成员变量。只有在实例化对象时才会执行。

静态代码块 

​class W1{
    public static int a;
    private int b;
    static {
        a = 20;
        System.out.println("aaa");
    }
}
public class Test3 {
    public static void main(String[] args) {
        W1.a = 50;
    }
}

 

 😉它不属于某一个对象,是类的属性,因此是在JVM加载类时开辟空间并初始化的。不管有多少个对象,就仅仅执行类加载这一次,如果有多个静态代码块,会按顺序执行。

这里还有同步代码块,后续会进行详解。

内部类

实例内部类

未被ststic修饰的内部类

class OutClass{
    static int a;
    public int b;
    int c;
    public void fun(){
        System.out.println("aaa");
    }
    public static void fun3(){
        System.out.println("aaaa");
    }
    class InterClass{
        int c;
        int a2;
        public int b2;
        private int c2;
        public void fun2(){
            a = 10;
            b = 20;
            c = 30;
            //内部类c
            System.out.println(c);
            //外部类c
            OutClass.this.c = 500;
            System.out.println(OutClass.this.c);
            fun();
            fun3();
        }
    }
}
public class Test4 {
    public static void main(String[] args) {
        //分别实例化外部类对象和内部类对象
        OutClass s = new OutClass();
        OutClass.InterClass s2 = s.new InterClass();
        s2.fun2();
    }
}

🎈内部类可以直接访问外部类任何修饰符,修饰的成员变量。

🎈如果内部类和外部类有相同的成员变量,在内部类成员方法中优先访问内部类中的成员变量(就近原则),想要访问外部类中相同的成员变量需要声明OutClass.this.c = 500;

🎈要访问实例内部类中成员,必须要实例化内部类的对象,而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类。

   OutClass s = new OutClass();
   OutClass.InterClass s2 = s.new InterClass();

🎈实例内部类中非静态成员方法中包含指向外部类对象的引用this

🎈外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

   静态内部类

被ststic修饰的内部类

class OutClass1{
    int a;
    private int b;
    static int c;
    public static void fun(){
        System.out.println("aaaaa");
    }
    static class InterClass1{
        int a2;
        private int b2;
        static int c2;
        public void fun2(){
            c = 20;
            fun();
        }
    }
}
public class Test5 {
    public static void main(String[] args) {
        OutClass1.InterClass1 s = new OutClass1.InterClass1();
        s.fun2();
    }
}

🐵静态内部类是不依赖于对象的,和静态成员变量有相似之处,它只能访问外部类中的静态成员变量和方法,要想访问非静态成员变量或者方法,就得创建对象。

🐵静态内部类创建对象是不依赖于外部类对象的,因此直接就可以创建内部类对象。

OutClass1.InterClass1 s = new OutClass1.InterClass1();

局部内部类

class OutClass1 {
    int a;
    private int b;
    static int c;

    public static void fun5() {
        class InterClass1 {
            int a2;
            private int b2;
            public void fun2() {
                System.out.println("aab");
            }
        }
        InterClass1 s1 = new InterClass1();
        s1.fun2();
    }
}
public class Test5 {
    public static void main(String[] args) {
        OutClass1 s1 = new OutClass1();
        s1.fun5();
    }
}

🧢故名思意就是创建在局部中的类,那么它只能在局部使用,局限性很大,且不能被public等访问修饰符修饰,一般使用很少。

匿名内部类后续进行详解

 续:构造成员方法

class Person2{
    int age;
    String name;
    public Person2(){
        System.out.println("aaa");
    }
    public Person2(int age, String name){
        this.age = age;
        this.name = name;
    }
}
public class Test6 {
    public static void main(String[] args) {
        Person2 stu = new Person2();
        Person2 stu2 = new Person2(21,"wu");
        System.out.println(stu2.name + stu2.age);

    }
}

 

🎉构造成员方法是用类实例化对象的一个必要条件,当我们自己没有写构造方法时,编译器会自己提供无参的构造方法,但我们一旦写了构造成员方法,编译器则不提供。

🎉构造成员方法名是和类名相同的,并且没有返回值。

🎉构造成员方法支持重载。

小结:

🐵面向对象编程思想的学习,需要我们深入的去理解,去思考,大量动手实践,相信会有不一样的收获。 

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小太空人w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值