打怪升级之小白的大数据之旅(十一)<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语法规范,对类进行封装,我是不是一句话总结了今天的全部内容(机智如我…)下一章,我们会介绍面向对象特性的第二个,继承,继承是学习多态的前提,是不是感觉内容环环相扣?如果有这种感觉就证明对面向对象的三大特性理解了,我很欣慰~~好了,欢迎大家后台留言吐槽…

posted @ 2021-04-06 19:36  数据民工  阅读(19)  评论(0)    收藏  举报