Java基础08-面向对象封装性、构造方法、对象和引用、参数传递

面向对象封装性

  • 引入封装
  • 为什么要封装
  • 封装的好处

User对象

package com.bjpowernode.javase.day08.test003;

public class User {
	
	int age;
}

UserTest测试对象

package com.bjpowernode.javase.day08.test003;

/**
用户测试类

对于当前程序来说:User类中的age属性在外部程序中可以随意访问,导致age属性的不安全。
一个User对象表示一个用户,用户的年龄不可能为负数,以下程序当中年龄值为负数,程序运行
时并没有报错。这是当前程序中存在的缺陷。

面向对象包括三大特征:
 - 封装
 - 继承
 - 多态
 
当前主要讲解的是封装机制。为什么要封装?封装有什么好处?

 封装的好处:
 
 	1.封装之后,对于那个事物来说,看不到这个事物比较复杂的那一面,只能看到该事物简单的那一面。
 	复杂性封装,对外提供简单的操作入口。照相机就是一个很好的封装的案例,照相机的实现原理非常复杂,
 	但是对于使用照相机的人来说,操作起来是非常方便的,是非常快捷的。还有像电视机也是封装的,电视机内存
 	实现非常复杂,但是对于使用者来说只需会使用遥控器即可。
  	
  	2.封装之后才会形成真正的“对象”,真正的“独立体”
  	
  	3.封装就意味着以后的程序可以重复使用。并且这个事物适应性比较强,在任何场合都可以使用。
  	
  	4.封装之后,对于事物本身,提高了安全性。【安全级别高】
  	
 */

public class UserTest {

	public static void main(String[] args) {
		
		// 创建User对象
		User user = new User();
		
		// 访问age
		// 读取年龄值【get】
		System.out.println("该用户年龄:" + user.age);
		
		// 修改年龄值【set】
		user.age = 20;
		
		// 读取年龄值【get】
		System.out.println("该用户年龄:" + user.age);
		
		// 修改年龄值【set】
		// 这里的age属性是完全暴露给外部程序的,对于程序员来说可以操作User对象当中所有的细节,导致User中部分数据不安全
		// 不建议这样,建议User类型进行封装,建议在外部程序中不能随意访问User对象当中的属性。这样可以保证属性的安全。
		user.age = -100;
		
		// 读取年龄值【get】
		System.out.println("该用户年龄:" + user.age);
		
	}

}

  • 封装的步骤

User对象

package com.bjpowernode.javase.day08.test004;

/**
封装的步骤:
	1.所有属性私有化,使用private关键字进行修饰,private表示私有化,修饰的所有数据只能在本类中进行访问
	
	2.对外提供简单的操作入口,也就是以后外部程序要想访问age属性,必须通过这些简单的入口进行访问
	
	3.set方法的命名规范:
		public void setAge(int a){
			age = a;
		}
	4.get方法的命名规范:
		public int getAge(){
			return age;
		}
	回想以下,一个属性通常访问的时候包括几种访问形式?
	- 第一种方式:想读取这个属性的值,读取get
	- 第二种方式:想修改这个属性的值,修改set
	
	需要大家先背会以下内容:
	setter anf getter方法没有static关键字;
	有static关键字修饰的方法怎么调用:类名.方法名(实参);
	没有static关键字修饰的方法怎么调用:引用.方法名(实参);
 */
public class User {
	
	//属性私有化
	private int age;
	
	//set方法没有返回值,因为set方法只负责修改数据
	/*
	public void setAge(int age) {		
		age = age;//java有就近原则,这里并没有给age属性赋值,这里的age都是局部变量age
	}
	*/
	public void setAge(int a) {
		//编写业务逻辑代码进行控制
		//age = a;
		if(a < 0 || a > 150) {
			System.out.println("对不起,你提供的 年龄不合法");
			return;
		}
		age = a;
	}
	
	public int getAge() {
		return age;
	}
}

UserTest测试对象

package com.bjpowernode.javase.day08.test004;

public class UserTest {

	public static void main(String[] args) {
		
		// 创建User对象
		User user = new User();
		
		// 编译报错,age属性私有化,在外部程序中不能直接访问
		// 从此之后age属性非常的安全,但是有点太安全了。
		// 对于目前的程序来说,age属性在外部访问不到了
		// System.out.println(user.name);
		
		//修改
		user.setAge(-100);
		
		//读取
		System.out.println(user.getAge());
	}

}

  • eclipse快速给类中私有变量添加相应的setter和getter方法,步骤如下:
    代码位置右键 --> Source --> Generate Getters and Setters
package com.bjpowernode.javase.day08.test004;

//顾客类
public class Customer {
	
	//属性
	private int id;	
	private String name;	
	private int age;	
	private String addr;
	
	
	//setter and getter方法
	public int getId() {
		return id;
	}

	public void setId(int id) {
		//安全控制
		this.id = id;
	}

	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 getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}


	
}

package com.bjpowernode.javase.day08.test004;

public class CustomerTest {

	public static void main(String[] args) {
		
		Customer c = new Customer();
		
		//私有的属性不能在外部直接访问
		//c.id = 100;
		
		//操作入口变成了只能通过set和get方法进行访问
		//在set方法和get方法执行过程中可以进行安全过滤
		c.setId(101010);
		c.setAge(100);
		c.setName("zhangsan");
		c.setAddr("青岛市黄岛区辛安街道");
		
		System.out.println(c.getId());
		System.out.println(c.getName());
		System.out.println(c.getAge());
		System.out.println(c.getAddr());
	}

}

构造方法

  • 引入构造方法
package com.bjpowernode.javase.day08.test005;

public class User {
	
	//无参数构造方法
	public User() {
		System.out.println("User's Default Constructor Invoke!");	
	}
	
	//有参数的构造方法
	public User(int i) {
		System.out.println("带有int类型参数的构造器");
	}
	//有参数的构造方法
	public User(String i) {
		System.out.println("带有String类型参数的构造器");
	}
	//有参数的构造方法
	public User(int i,String j) {
		System.out.println("带有int,String类型参数的构造器");
	}
}

package com.bjpowernode.javase.day08.test005;

/**
	关于java类中的构造方法:
 		1.构造方法又称:构造函数 / 构造器 / Constructor 
 		
   		2.构造方法语法结构:
			【修饰符列表】构造方法名(形式参数列表){
				构造方法体;
			}
			
		3.回顾方法体结构:
			【修饰符列表】返回值类型 方法名(形式参数列表){
				方法体;
			}
			
		4.对于构造方法来说,“返回值类型”不需要指定,并且也不能写void,
		只要写上void,那么这个方法就变成普通方法了。
		
		5.对于构造方法来说,构造方法的方法名必须和类名保持一致
		
		6.构造方法的作用?
			构造方法存在的意义是,通过构造方法的调用,可以创建对象
		
		7.构造方法应该怎么调用?
			普通方法是这样调用的:
				方法修饰符中有static的时候:	类名.方法名(实参列表)
			 	方法修饰符中没有static的时候:引用.方法名(实参列表)
			构造方法是这样调用的:
				new 构造方法名(实参列表)
				
		8.构造方法结束之后,有返回值吗?
			每一个构造方法实际上执行结束之后都有返回值,但是这个"return 值;"这样的语句不需要写,
			构造方法结束的时候java程序自动返回值,并且返回值类型就是类本身,所以返回值类型不需要编写。
			
		9.eclipse快捷键:单行注释:ctrl + / ; 多行注释:ctrl + shift + /
		
		10.当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器
		
		11.当一个类显示的将构造方法定义出来了 ,那么系统不再默认为这个类型提供缺省构造器。建议开发中手动的为当前类提供
		无参数构造方法,因为无参数构造方法太常用了。
		
		12.构造方法支持重载机制,在一个类中编写多个构造方法,这多个构造方法显然已经构成方法重载机制。
 */
public class ConstructorTest01 {

	public static void main(String[] args) {
		
		//创建User对象
		//使用User类的构造方法来完成对象的创建	
		//以下程序创建了4个对象,只要构造函数调用就会创建对象,并且一定是在“堆内存”中开辟内存空间。
		User u1 = new User();		
		User u2 = new User(10);		
		User u3 = new User("zhangsan");		
		User u4 = new User(10,"zahngsan");
				
		// int i = sumInt(100);
		
		//普通方法中,修饰符列表有static,调用形式:类名.方法名
		ConstructorTest01.doSome(); 
		doSome();//同一个类中可以省略类名
		
		//普通方法中,修饰符列表中没有static ,调用形式:引用.方法名
		//doOther方法在ConstructorTest01类当中,所以需要创建ConstructorTest01对象
		//创建ConstructorTest01对象,调用无参数构造方法
		ConstructorTest01 t = new ConstructorTest01();//一个类中没有任何构造方法的话,系统默认提供一个无参数构造器
		t.doOther();
	}
	
	public static void doSome() {
		System.out.println("do Some!");
	}
	
	public void doOther() {
		System.out.println("do Other!");
	}
	
	

}

  • 构造方法的作用
package com.bjpowernode.javase.day08.test005;

// 账户类
public class Account {

	//账号
	private String actno;//实例变量/对象变量,也就是说,必须先有对象才能有对应的实例变量,
	
	//余额
	private double balance;
	
	//无参构造器
	public Account() {
		//初始化实例变量的内存空间
		//actno = null;
		//balance = 0.0;
		
	}
	
	public Account(String s) {
		actno = s;
		//balance = 0.0;
	}
	
	public Account(double d) {
		//actno = null;
		balance = d;
	}
	
	public Account(String s,double d) {
		actno = s;
		balance = d;
	}

	public String getActno() {
		return actno;
	}

	public void setActno(String actno) {
		this.actno = actno;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	
}

package com.bjpowernode.javase.day08.test005;

/**
	构造方法的作用:
		1.创建对象
		2.初始化实例变量
		
	成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量
	实例变量没有手动赋值的时候,系统默认赋值,那么这个系统默认赋值是在什么时候完成的呢?
		是在类加载的时候吗?
			不是,因为类加载的时候只将字节码文件和代码片段加载到方法区内存,还没来得及创建对象。
		所以此时实例变量并没有初始化。
		
		实际上,实例变量的内存空间是在构造方法执行过程中完成开辟的,完成初始化的。
		系统在默认赋值的时候,也是在构造方法执行过程中完成的赋值。
		
	实例变量默认赋值:
	byte,short,int,long 0
	float,double 0.0
	boolean false
	引用数据类型 null
	
	实例变量存储在JVM的堆内存java对象的内部
 */
public class ConstructorTest02 {

	public static void main(String[] args) {
		
		//在eclipse当中怎么查看访问的是哪个属性,查看访问的是哪个方法?
		//按ctrl键,鼠标移动到查看的元素上,出现下划线的时候开始单击。
		//另外,在一个类中元素过多,想快速查看,在当前类中使用ctrl + o快捷键,然后输入要查找的元素名称,该名称不一定输入全名称
		
		//创建对象
		Account acc1 = new Account();		
		System.out.println("账号:" + acc1.getActno());
		System.out.println("余额:" + acc1.getBalance());
		
		Account acc2 = new Account("111");
		System.out.println("账号:" + acc2.getActno());
		System.out.println("余额:" + acc2.getBalance());		
		
		Account acc3 = new Account(100.0);
		System.out.println("账号:" + acc3.getActno());
		System.out.println("余额:" + acc3.getBalance());	
		
		Account acc4 = new Account("acc4-1",200.0);
		System.out.println("账号:" + acc4.getActno());
		System.out.println("余额:" + acc4.getBalance());	
	}

}

  • 利用系统快捷方式快速生成构造方法
    代码位置右键 --> Source --> Generate Constructor using Fields…
  • 快捷键,按列同步更改代码:快捷图标
    在这里插入图片描述
package com.bjpowernode.javase.day08.test005;

public class Customer {
	
	String name;
	
	int no;
	
	String addr;
	
	//无参数构造器
	public Customer() {
		
	}
	
	//有参数构造器
	public Customer(String a, int b, String c) {
		name = a;
		no = b;
		addr = c;
	}


	public Customer(int no) {
		super();
		this.no = no;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public String getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}


	
	
}

package com.bjpowernode.javase.day08.test005;

public class ConstructorTest03 {
	public static void main(String[] args) {
		
		Customer c1 = new Customer();		
		System.out.println(c1.getNo());
		System.out.println(c1.getName());
		System.out.println(c1.getAddr());
		
		Customer c2 = new Customer("zhangsan",111,"青岛市");		
		System.out.println(c2.getNo());
		System.out.println(c2.getName());
		System.out.println(c2.getAddr());
	}
}

对象和引用

  • 对象:目前在使用new运算符在堆内存中开辟的内存空间称为对象。
  • 引用:是一个变量,不一定是局部变量,还可能是成员变量。引用保存了内存地址,指向了堆内存当中的对象。
  • 所有访问实例相关的数据,都需要通过“引用.”的方式访问,因为只有通过引用才能找到对象。
  • 只有一个空的引用,访问对象的实例相关的数据会出现空指针异常。
class Student{
	Computer com;//com是一个引用【实例变量】
	public static void doSome(){
		Computer cc;//cc是一个引用【局部变量】
	}
}

参数传递

  • 主要研究和学习的是方法在调用的时候,涉及到参数传递的问题,到底是怎么传递数据的呢?
int i = 10;
int j = i;//i传递给j,实际上是将i变量中保存的10传递给j了,j实际上是一块全新的内存空间。

User u = 0x1234;
User u2 = u;//u传递给u2,实际上是将0x1234这个值赋值给u2了,u和u2实际上是两个不同的局部变量
            //但是它们这两个变量指向堆内存中同一个java对象
  • java语言当中调用的时候涉及到参数传递的问题
    参数传递的是变量中的具体值
package com.bjpowernode.javase.day08.test006;

/**
	java语言当中调用的时候涉及到参数传递的问题
	参数传递的是变量中的具体值
		
	int i = 10;
	add(i); 等同于 add(10)
 */
public class Test01 {
	public static void main(String[] args) {
		
		int i = 10;
		add(i);//add方法调用的时候,给add方法传递了一个变量i,到底传的是什么?
		System.out.println("main -->" + i);
	}
	
	public static void add(int i) {		
		i ++;
		System.out.println("add -->" + i);
	}
}

在这里插入图片描述

  • 内容2
package com.bjpowernode.javase.day08.test006;

public class Test02 {

	public static void main(String[] args) {
		 
		//User u = 0x1234;
		//传递u给add方法的时候,实际上传递的是u变量中保存的值,只不过这个值是一个java对象的内存地址
		User u = new User(20);
		add(u);//等同于:add(0x1234);
		System.out.println("main -->" + u.age);//21
		
	}
	public static void add(User u) {
		u.age ++;
		System.out.println("add -->" + u.age);//21
	}

}

class User{
	//实例变量
	int age;
	
	//构造方法
	public User(int i) {
		age = i;
	}
}

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值