打怪升级之小白的大数据之旅(十一)<Java基础语法之面向对象的三大特性--封装>
打怪升级之小白的大数据之旅(十一)
Java基础语法之面向对象的三大特性–封装
上次回顾:
上一章,对面向对象的方法进行了分享,对于方法的理解与使用,我们着重知道它的调用方式就可以了,底层的一些思想能理解最好,毕竟我们是大数据不是Java高级工程师~~
本章开始,我将面向的三大特性依次介绍给大家,还是老样子,细节点很多,我们只需要理解并多敲代码,自然就能记住.
面向对象的三大特性
引言
面向对象的三大特性:封装,继承,多态,我在面向对象开篇介绍过,还记得这张图么
- 封装
![封装]()
- 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?
- 我们使用的电脑,内部有CPU、硬盘、键盘、鼠标等等,每一个部件通过某种连接方式一起工作,但是各个部件之间又是独立的
- 现实生活中,每一个个体与个体之间是有边界的,每一个团体与团体之间是有边界的,而同一个个体、团体内部的信息是互通的,只是对外有所隐瞒
- 面向对象编程语言是对客观世界的模拟,客观世界里每一个事物的内部信息都是隐藏在对象内部的,外界无法直接操作和修改,只能通过指定的方式进行访问和修改。
- 封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性
封装
概念
-
随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要遵循“高内聚、低耦合”,而“高内聚,低耦合”的体现之一:
1). 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
2). 低耦合:仅对外暴露少量的方法用于使用 -
封装就是把该隐藏的隐藏起来,该暴露的暴露出来,其暴露程度在Java中就是利用权限修饰符来控制
权限修饰符
| 修饰符 | 本类 | 本包 | 其他包子类 | 任意位置 |
|---|---|---|---|---|
| private | √ | × | × | × |
| 缺省 | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
权限修饰符可以修饰:
1). 外部类:public和缺省
2). 成员变量/成员方法/构造器/成员内部类: public,protected,缺省和private
-
示例代码一: 本包非子类与子类
package com.atguigu.test01.access1; public class Father { public int a; protected int b; int c; private int d; public static int e; protected static int f; static int g; private static int h; } class Mother{ public Mother(){ } }当前包非子类的情况
package com.atguigu.test01.access1; //本包非子类中不同权限修饰符的情况 public class Other { public static void method(){ Father obj = new Father(); System.out.println(obj.a); System.out.println(obj.b); System.out.println(obj.c); //System.out.println(obj.d);//跨类不可见 System.out.println(Father.e); System.out.println(Father.f); System.out.println(Father.g); //System.out.println(h);//跨类不可见 } public void fun(){ Father obj = new Father(); System.out.println(obj.a); System.out.println(obj.b); System.out.println(obj.c); //System.out.println(obj.d);//跨类不可见 System.out.println(Father.e); System.out.println(Father.f); System.out.println(Father.g); //System.out.println(h);//跨类不可见 } }当前包子类的情况
package com.atguigu.test01.access1; //本包子类中,权限修饰符,修饰情况 public class Sub extends Father{ public static void method(){ //静态直接访问非静态都不行 /*System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d);*/ Father obj = new Father(); System.out.println(obj.a); System.out.println(obj.b); System.out.println(obj.c); //System.out.println(obj.d);//跨类不可见 System.out.println(e); System.out.println(f); System.out.println(g); //System.out.println(h);//跨类不可见 } public void fun(){ System.out.println(a); System.out.println(b); System.out.println(c); //System.out.println(d);//跨类不可见 System.out.println(e); System.out.println(f); System.out.println(g); //System.out.println(h);//跨类不可见 } }代码示例一图:
![本包非子类与子类的情况]()
-
示例代码二:挎包非子类与子类
package com.atguigu.test01.access1; public class Father { public int a; protected int b; int c; private int d; public static int e; protected static int f; static int g; private static int h; } 挎包非子类情况 ```java package com.atguigu.test01.other; import com.atguigu.test01.access1.Father; public class Another { public static void method(){ Father obj = new Father(); System.out.println(obj.a); //System.out.println(obj.b);//跨包非子类不可见 //System.out.println(obj.c);//跨包不可见 //System.out.println(obj.d);//跨类不可见 System.out.println(Father.e); //System.out.println(Father.f);//跨包非子类不可见 //System.out.println(Father.g);//跨包不可见 //System.out.println(h);//跨类不可见 } public void fun(){ Father obj = new Father(); System.out.println(obj.a); //System.out.println(obj.b);//跨包非子类不可见 //System.out.println(obj.c);//跨包不可见 //System.out.println(obj.d);//跨类不可见 System.out.println(Father.e); //System.out.println(Father.f);//跨包非子类不可见 //System.out.println(Father.g);//跨包不可见 //System.out.println(h);//跨类不可见 } }挎包子类情况
package com.atguigu.test01.other; import com.atguigu.test01.access1.Father; public class Son extends Father{ public static void method(){ //静态直接访问非静态都不行 /*System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d);*/ Father obj = new Father(); System.out.println(obj.a); //System.out.println(obj.b);//跨包的静态成员 //不能访问非静态的protected //System.out.println(obj.c);//跨包不可见 //System.out.println(obj.d);//跨类不可见 System.out.println(e); System.out.println(f); //System.out.println(g);//跨包不可见 //System.out.println(h);//跨类不可见 } public void fun(){ System.out.println(a); System.out.println(b); //System.out.println(c);//跨包不可见 //System.out.println(d);//跨类不可见 System.out.println(e); System.out.println(f); //System.out.println(g);//跨包不可见 //System.out.println(h);//跨类不可见 } }示例代码二图:
![挎包示例图]()
-
示例代码三: 缺省的类
package com.atguigu.test01.access1; class Mother { }package com.atguigu.test01.access1; public class Daughter extends Mother{ }package com.atguigu.test01.other; //Mother类是缺省的,跨包不能使用 public class Daughter extends Mother{ }示例代码三图:
![缺省的类]()
-
示例代码四: 公共的类,缺省的构造器,挎包使用问题(构造器下面会讲到)
// 情况一 package com.atguigu.test01.access1; public class Fu { Fu(){ } }// 情况二 package com.atguigu.test01.access1; public class Zi extends Fu{ }情况三 package com.atguigu.test01.other; import com.atguigu.test01.access1.Fu; public class Zi extends Fu{ Zi() { super(); } }// 情况四 package com.atguigu.test01.access1; public class Neighbor { public static void main(String[] args) { Fu f = new Fu(); } }// 情况五 package com.atguigu.test01.other; import com.atguigu.test01.access1.Fu; public class AnotherNeighbor { public static void main(String[] args) { Fu f = new Fu(); } }示例代码四图:
![公共的类]()
封装的实现
-
知道了权限修饰符的作用后,下面就要进行封装的实现了,在Java中,封装多用于对成员变量的封装
-
成员变量封装的目的
1). 隐藏类的实现细节,就像引言的中说的那样,该暴露的暴露,该隐藏的隐藏
2). 让调用者只能通过预定的方法来访问数据,限制调用者对成员变量的不合理访问,确保对象信息的安全性和完整性
3). 便于修改,提高代码的可维护性 -
语法格式
1).使用private修饰成员变量,使其成为只能本类内访问的私有属性
private 数据类型 变量名 ;
2). 定义getter/setter方法,让调用者可以访问私有属性
代码如下:public class Chinese { // 将成员变量定义为私有属性 private static String country; private String name; private int age; private boolean marry; // 定义getter/setter方法,让调用者可以访问私有属性 public static void setCountry(String c){ country = c; } public static String getCountry(){ return country; } public void setName(String n) { name = n; } public String getName() { return name; } public void setAge(int a) { age = a; } public int getAge() { return age; } public void setMarry(boolean m){ marry = m; } public boolean isMarry(){ return marry; } }
初识this关键字
- this关键字我们着重在下一章继承中讲,为了便于理解下面的构造器,因此先提一下this关键字
- 当局部变量与成员变量同名的时候,为了让计算机可以区分,就会使用this关键字
- 当局部变量与类变量(静态成员变量)同名时,在类变量前面加“类名.";
- 当局部变量与实例变量(非静态成员变量)同名时,在实例变量前面加“this.”
- this点当前对象的引用,也就是说,谁调用this,this代表的就是谁
- 示例代码:
public class Chinese { private static String country; private String name; private int age; public static void setCountry(String country){ Chinese.country = country; } public static String getCountry(){ return country; } 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; } }
构造器
-
在我们创建一个具体的实例(new创建对象)时,所有成员变量都是默认值,我们每次都需要挨个为他们赋值,为了增加代码复用性,此时,我们就需要使用构造器了
注意: 构造器只为实例变量初始化,不为静态变量初始化 -
作用
- 初始化对象属性
-
语法格式
// 无参构造器 【修饰符】 构造器名(){ // 实例初始化代码 } // 带参构造器 【修饰符】 构造器名(参数列表){ // 实例初始化代码 } -
格式说明
– 构造器的名字必须与类名相同
– 构造器与普通方法类似,但是没有返回值,也没有void
– 构造器也可以重载
– 系统会默认给出无参构造器,当显示写出一个构造器,隐藏的默认构造器就不再存在 -
示例:
public class Student{ private String name; private ing age; // 定义无参构造器 public Student(){} // 定义带参构造器 public Student(String name, int age){ this(name) ; // 调用本类的其他构造器,注意这句必须在构造体第一行 this.age = age; } } -
this调用构造器
前面介绍了this关键字,下面使用示例来阐述this在构造器中的使用// 格式:this(参数列表); public Employee(){ } public Employee(String id){ this.id=id; } public Employee(String id, String name){ this(id);//this调用一个参数的构造器 this.name = name; } public Employee(String id, String name, double salary, char gender){ this(id,name);//this调用2个参数的构造器 this.salary = salary; this.gender = gender; }
注意:this调用构造器的语句,只能构造器中第一行位置。
Java bean
-
JavaBean是Java语言在编写类的一种标准规范
-
语法格式:
public class ClassName{ //成员变量 //构造方法 //无参构造方法【必须】 //有参构造方法【建议】 //getXxx() //setXxx() //其他成员方法 } -
格式说明:
1). 类必须是具体的(非抽象)和公共的
2). 具有无参数的构造器
3). 成员变量进行私有化, 并且提供操作成员变量的公共方法setter/getter
4). 实现序列化接口
5). 不涉及业务逻辑,主要承载数据 -
示例代码
public class Student { // 成员变量 private String name; private int age; // 构造方法 public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } // get/set成员方法 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 String getInfo(){ return "姓名:" + name + ",年龄:" + age; } } -
使用该类的格式:
public class TestStudent { public static void main(String[] args) { // 无参构造使用 Student s = new Student(); s.setName("柳岩"); s.setAge(18); System.out.println(s.getName() + "---" + s.getAge()); System.out.println(s.getInfo()); // 带参构造使用 Student s2 = new Student("赵丽颖", 18); System.out.println(s2.getName() + "---" + s2.getAge()); System.out.println(s2.getInfo()); } }
总结
本章对面向对象三大特性的封装进行了介绍,在Java中,封装最常的用途就是配合构造器与JavaBean语法规范,对类进行封装,我是不是一句话总结了今天的全部内容(机智如我…)下一章,我们会介绍面向对象特性的第二个,继承,继承是学习多态的前提,是不是感觉内容环环相扣?如果有这种感觉就证明对面向对象的三大特性理解了,我很欣慰~~好了,欢迎大家后台留言吐槽…





浙公网安备 33010602011771号