java面向对象三大特性之——封装

文章目录

1、封装(private)

​ 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
​ 隐藏实现细节,提供公共的访问方式
​ 提高了代码的复用性
​ 提高安全性。
封装原则:
​ 将不需要对外提供的内容都隐藏起来。
​ 把属性隐藏,提供公共方法对其访问。
封装中的private关键字介绍:
​ 1、是一个权限修饰符。
​ 2、可以修饰成员(成员变量和成员方法)
​ 3、被private修饰的成员只在本类中才能访问。
练习:
​ 随机找身边的一个事物,定义一个类
​ 成员变量用private修饰,提供公共的getXxx()和setXxx()方法
​ 以及提供一个可以输出所有成员变量的show()方法
​ 然后定义一个测试类,去创建对象使用看看

class Person {private String name;private int age;public void setName(String s) {
​        name = s;}public String getName() {return name;}public void setAge(int i) {
​        age = i;}public int getAge() {return age;}//提供一个方法可以输出打印所有的成员变量public void show() {//被private修饰的成员方法,只能在本类中进行访问fun2();System.out.println("姓名:" + name + ",年龄:" + age);}private void fun2() {System.out.println("这是一个被private修饰的成员方法");}
}
public class PrivateDemo1 {public static void main(String[] args) {//创建Person对象Person p1 = new Person();//因为成员变量都被private私有的关键字修饰了,所以在其他类中访问不到。
//        p1.name;
//        p1.age;//只能调用公共方法进行获取String name = p1.getName();int age = p1.getAge();System.out.println(name + "---" + age);//通过公共的方法对成员变量进行赋值
​        p1.setName("刘XX");
​        p1.setAge(18);
​        p1.show();//被private修饰成员方法,在其他类中也是不可以被访问的。
//        p1.fun2();}
}

this的引入:
this:代表所在类的对象引用
记住:
方法被哪个对象调用,this就代表那个对象
定义成员变量

private String name;private int age;

提供公共的getXxx()和setXxx()方法
回想一下,我们之前给变量进行命名的时候,有一个规则:见名知意
所以我们改一下
我们根据变量命名规则的见名之意的方式修改了形参的名字,但是呢
运行程序后发现,虽然我们也调用了方法,也进行了传参,但是,结果依旧没有成功赋值.
这是为什么呢?
因为变量的调用遵循就近原则
我们理想上,是想让传进来的这个参数赋值给该对象的成员变量
实际上传进来的实参的值后面进行赋值的时候,还是赋值给方法上的变量,与成员变量没有关系.
想的是,将传进来的name值赋值给当前对象的name值

public void setName(String name) { //"姜XX"//Student3.name这种写法,我们没有介绍过

如果有一个东西可以代表当前调用该方法的对象就好了
谁可以代替当前方法的对象呢?
java提供了一个关键字:this

       Student3.name = name;//这样写,就代表将传进来的参数,赋值给当前调用该方法的对象的成员变量namethis.name = name;}public String getName() {//其实这里隐藏了一个this关键字,代表的是返回当前调用该方法的对象的成员变量namereturn this.name;}public void setAge(int age) {this.age = age;}public int getAge() {return age;    }public void show() {System.out.println("姓名:" + name + ",年龄:" + age);}
}
public class StudentDemo2 {public static void main(String[] args) {//创建学生对象并对成员变量进行赋值Student3 s1 = new Student3();//对s1对象的姓名进行赋值
​        s1.setName("姜XX");
​        s1.setAge(18);//调用show()方法查看所有成员变量值
​        s1.show();}

构造方法:

​ 构造方法的目的是为对象中的数据进行初始化。
格式:
​ 1、方法名与类名相同
​ 2、没有返回值类型,连void都没有
​ 3、没有具体的返回值

class Student {private String name;private int age;Student(){System.out.println("这是无参的构造方法");}//getXxx()和setXxx()方法public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}public void show() {System.out.println("姓名:" + name + ",年龄:" + age);}
}
public class StructureDemo1 {public static void main(String[] args) {//创建对象Student s = new Student();
//        s.show();}
}

有些同学开始思考:
​ 我们在学习构造方法之前,也是new对象出来,现在知道了,内部一直都是调用一个无参的构造方法,但是呢,我们在类中并没有去写出来构造方法,所以问题是我们一直用的构造方法来自哪里呢?
注意
​ 1、如果我们没有给出构造方法,JVM就会自动的提供一个无参的构造方法给我们。
​ 2、如果我们给出了构造方法,JVM就不会再提供默认的无参构造方法了。
​ 如果我们没有给出无参构造方法,却给出了其他的带参构造方法,JVM就不再会提供默认的无参构造方法。只要我们给出了构造方法,无论是有参还是无参,JVM就永远不会再提供无参的构造方法。
​ 3、构造在同一个类中也是可以发生重载的。(方法名一致,参数列表不一样,与返回值无关)
构造方法的作用:
​ 1、可以在创建对象的时候给对象的成员变量进行赋值
​ 给对象的成员变量进行赋值的两种方式:
​ 1)使用类提供的公共的setXxx()方法给成员变量进行赋值
​ 2)使用带参数的构造方法给私有的成员变量进行赋值,
​ 注意形参的变量名和成员变量名一样的时候,需要配合this关键字一起使用

class Structure {private String name;private int age;Structure() {System.out.println("这是我们自己写的无参构造方法");}Structure(String name) {System.out.println("这是我们自己写的带name参数的带参构造方法");this.name = name;}Structure(int age){System.out.println("这是我们自己写的带age参数的带参构造方法");this.age = age;}Structure(String name,int age){System.out.println("这是我们自己写的带所有成员变量的参数的带参构造方法");this.name = name;this.age = age;}public void show() {System.out.println("姓名:" + name + ",年龄:" + age);}
}
public class StructureDemo2 {public static void main(String[] args) {Structure s1 = new Structure();//能看到地址值说明咱们的对象已经被new了出来System.out.println(s1);System.out.println("=======================");//创建第二个对象Structure s2 = new Structure("李XX");
​        s2.show(); //李XX,0System.out.println("=======================");//创建第三个对象Structure s3 = new Structure(17);
​        s3.show();//null,17System.out.println("=======================");//创建第四个对象Structure s4 = new Structure("张XX",18);
​        s4.show();}
}

无参构造创建对象内存执行顺序:
在这里插入图片描述

带参构造创建对象内存执行顺序:
在这里插入图片描述
类的组成:
​ 成员变量
​ 构造方法
​ 成员方法:
​ 根据有无返回值:
​ 1、没有返回值的成员方法
​ 2、有返回值的成员方法
​ 根据有无参数:
​ 1、无参的成员方法
​ 2、有参数的成员方法

 class Student2 {private String name;private int age;//无参构造方法Student2() {}//包含所有成员变量的参数的构造方法Student2(String name, int age) {this.name = name;this.age = age;}//公共的getXxx()方法和setXxx()方法public void setName(String name) {this.name = name;}public String getName() {return name;}public void setAge(int age) {this.age = age;}public int getAge() {return age;}//无参无返回值的成员方法public void printHello() {System.out.println("HelloWorld");}//无参有返回值的成员方法public String getTianQi() {return "晴天";}//带参无返回值的成员方法public void sum(int a, int b) {System.out.println(a + b);}//带参有返回值的成员方法public String concat(String s1, String s2) {return s1 + s2;}//定义一个方法将所有的成员变量输出public void show() {System.out.println("姓名:" + name + ",年龄:" + age);}
}
public class StudentDemo {public static void main(String[] args) {//使用无参的构造方法创建对象Student2 s1 = new Student2();
​        s1.show();//调用无参无返回值的成员方法
​        s1.printHello();//调用无参有返回值的成员方法String tianqi = s1.getTianQi();System.out.println(tianqi);//调用带参有返回值的成员方法String s = s1.concat("数加科技","yyds");System.out.println(s);//调用带参无返回值的成员方法
​        s1.sum(12,45);//使用带参的构造方法创建对象Student2 s2 = new Student2("陶",16);
​        s2.show();}
}

static介绍:
引入:定义一个人的类
​ 经过测试发现,我们举例子的时候,都是中国人,国籍都一样,都是中国​,一样的国籍,每次创建的时候,都会在堆内存开辟一个这样的变量空间总觉得有点浪费。有没有什么办法,让所有一样国籍的人共用一个国籍的值, 针对多个对象拥有共同的成员变量,值是一样的时候.
​ Java提供了一个关键字给我们处理这样的情况,这个关键字叫做:static,可以修饰成员变量和成员方法,修饰成员变量的时候,可以让多个对象共用一个成员变量的值。
父类中的静态成员可以看作是一个全局共享的

class Person{//姓名private String name;//年龄private int age;//国籍
//    private String nationality;private static String nationality;public Person() {}public Person(String name, int age, String nationality) {this.name = name;this.age = age;this.nationality = nationality;}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getNationality() {return nationality;}public void setNationality(String nationality) {this.nationality = nationality;}public void show(){System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+nationality);}
}
public class PersonDemo {public static void main(String[] args) {//创建第一个对象Person p1 = new Person("宋轶",26,"中国");
​        p1.show();//创建第二个对象Person p2 = new Person("胡歌",30);
​        p2.show();//创建第三个对象Person p3 = new Person("钱学森",18);
​        p3.show();        System.out.println("=================================");
​        p1.setNationality("俄罗斯");
​        p1.show();
​        p2.show();
​        p3.show();}
}

static的静态内存图:
在这里插入图片描述

​ static的特点:
它可以修饰成员变量和成员方法
​ 1、随着类的加载而加载
​ 运行之前会将class类文件加载到方法区中,而被static修饰的成员是随着类的加载而加载,所以被static修饰的成员在方法区存放。
​ 回想一下main方法
​ 2、优先于对象存在
​ 3、被类所有的对象共享
​ 举例:所有的中国人的国籍信息都一样
​ 什么时候使用static关键字呢?
​ 如果说明某个成员变量是被所有对象共享的,那么它就应该被定义为静态的。
​ 举例:
​ 哈罗单车:(可以被static修饰)
​ 自己的水杯:(不可以被static修饰)
​ 4、被静态修饰的成员可以直接通过类名调用
​ 一般情况下,我们今后开发的时候,只要看到类中有静态的成员变量或者成员方法
​ 今后调用的时候,一律用 类名.静态成员 这样的方式区调用
​ 推荐使用类名的方式调用,这也是规范。
​ 通过调用的方式不同区分不同的成员
​ 所以被静态修饰的成员,一般情况下被称之为:类成员,与类相关的

class Demo2{//定义一个非静态的成员变量int a = 10;//定义一个静态的成员变量static int b = 20;
}
public class StaticDemo1 {public static void main(String[] args) {
//        Demo2 d1 = new Demo2();
//        System.out.println(d1.a);
//        System.out.println(d1.b);System.out.println(Demo2.b);}
}

例题标准类代码3.0版本,一个标准的手机类
​ 分析:
​ 手机:
​ 属性:品牌,颜色,价格
​ 行为:打电话,发短信,学习
​ 类:
​ 成员变量:brand,color,price(使用private修饰)
​ 构造方法:无参构造方法,带参构造方法
​ 成员方法:setXxx()和getXxx()方法
​ show():输出所有的成员变量

public class Phone {//定义成员变量private String brand;private String color;private int price;//定义构造方法Phone() {}Phone(String brand, String color, int price) {this.brand = brand;this.color = color;this.price = price;}//定义公共的setXxx()和getXxx()public void setBrand(String brand) {this.brand = brand;}public String getBrand() {return brand;}public void setColor(String color) {this.color = color;}public String getColor() {return color;}public void setPrice(int price) {this.price = price;}public int getPrice() {return price;}//定义一个可以输出所有成员变量的方法public void show() {System.out.println("品牌:" + brand + ",颜色:" + color + ",价格:" + price);}
}
class PhoneDemo {public static void main(String[] args) {//使用无参的构造方法创建对象,并使用setXxx()给成员变量进行赋值System.out.println("=======使用无参的构造方法创建对象,并使用setXxx()给成员变量进行赋值=======");Phone p1 = new Phone();System.out.println("未赋值前:");
​        p1.show();
​        p1.setBrand("华为");
​        p1.setColor("黑色");
​        p1.setPrice(4999);System.out.println("赋值后:");
​        p1.show();       System.out.println("======================================");System.out.println("=======使用带参数的构造方法创建对象,并使用getXxx()获取成员变量=======");Phone p2 = new Phone("锤子手机","白色",8888);String brand = p2.getBrand();String color = p2.getColor();int price = p2.getPrice();System.out.println("品牌["+brand+"]\t颜色["+color+"]\t价格["+price+"]");}
}

静态成员访问的问题:
​ 1、static可以修饰成员变量和成员方法
​ 2、​ 非静态的成员方法:
​ 1)访问的是非静态的成员变量
​ 可以
​ 2)访问的是静态的成员变量
​ 可以
​ 3)访问的是非静态的成员方法
​ 可以
​ 4)访问的是静态的成员方法
​ 可以
​ 总结:非静态的成员方法可以访问静态的成员也可也访问非静态的成员
​ 静态的成员方法:
​ 1)访问的是非静态的成员变量
​ 不可以
​ 2)访问的是静态的成员变量
​ 可以
​ 3)访问的是非静态的成员方法
​ 不可以
​ 4)访问的是静态的成员方法
​ 可以
​ 总结:静态的成员方法只能访问静态的成员

class Demo3{//非静态的成员变量int a = 10;//静态的成员变量static int b = 20;//非静态的成员方法public void fun1(){System.out.println(a);System.out.println(b);fun2();fun3();}public static void fun2(){//Error:(47, 28) java: 无法从静态上下文中引用非静态 变量 a
//        System.out.println(a);
//        System.out.println(b);
//        System.out.println("这是静态的成员方法fun2");//Error:(51, 9) java: 无法从静态上下文中引用非静态 方法 fun3()
//        fun3();fun4();}public void fun3(){System.out.println("这个是非静态的成员方法fun3");}public static void fun4(){System.out.println("这是静态的成员方法fun4");}
}
public class StaticDemo2 {public static void main(String[] args) {Demo3 d = new Demo3();
//        d.fun1();Demo3.fun2();fun();}
  public static void fun(){System.out.println("helloworld");}
}

​ 讲解代码块的目的:今后面试的时候,会有相关程序题,需要熟悉不同的代码块的执行顺序。
代码块
​ 在Java中,使用{}括起来的代码被称为代码块
​ 根据其位置和声明的不同,可以分为
​ 局部代码块(当作正常的代码看待)
​ 格式:只在方法中出现,使用大括号括起来的代码叫局部代码块
​ 好处:使用完毕及早释放,提高内存的使用率
​ 执行顺序:在一个方法中,自上而下的顺序执行
​ 构造代码块
​ 在类中方法外定义,每次调用构造方法的时候,都会先执行一遍构造代码块再执行构造方法
​ 构造代码块 – 构造方法
​ 如果在main方法中new对象的时候,也有局部代码块,执行顺序自上而下
​ 静态代码块
​ 被static修饰的代码块,定义在类中方法外
执行顺序:
静态代码块 – 构造代码块 – 构造方法
​ static代码块一旦被执行过一次后,同一个程序不会重复执行。
​ 静态的内容是属于类的本身,程序的开始到结束只会加载一次,不会重复加载。
​ 同步代码块(多线程讲解)。

class Demo {//无参构造方法Demo() {System.out.println("Demo无参构造方法");}//构造代码块{int x = 200;System.out.println(x);}//静态代码块static {int w = 99;System.out.println(w);}
}
public class CodeDemo {CodeDemo() {int y = 400;System.out.println(y);}{int q = 500;System.out.println(q);}static {int r = 700;System.out.println(r);}public static void main(String[] args) {{int a = 100;System.out.println(a);}int a2 = 11;System.out.println(a2);{int b = 200;System.out.println(b);}System.out.println("============================");
        System.out.println(a);
//        Demo demo = new Demo();
//        Demo demo1 = new Demo();Demo d = new Demo();CodeDemo codeDemo = new CodeDemo();}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值