封装

丶灬走出姿态 提交于 2020-01-31 22:31:45

3、封装

概述:

隐藏对象的属性的实现细节,仅对外提供公共访问方式

案例:

​ 使用这个案例中 发现了一个问题,通过成员变量可以赋值一些非法的数据。
​ 赋值前应先进行判断。判断在哪里做比较合适呢?

判断应该定义在student类中,而我们在成员变量的位置不能判断。因为做数据校验,必须要依靠逻辑语句。逻辑语句应该定义在方法中。最终决定在student类中提供一个方法校验。

	public void setAge(int a) {
		if (a < 0 || age > 120) {
			System.out.println("你给的年龄有问题");

		} else {
			age = a;
		}
	}
	

我们给出了方法进行校验,但是,它不用方法,还是直接赋值了。方法就没有起到作用。

就应该要求它必须使用方法

		// 创建学生对象
		Student s = new Student();
		// 给成员变量赋值
		s.setAge(18); 
		s.name = "周十七";
		s.show();
		s.age = -17;
		s.show ();
	}

怎么强制使用方法,不走成员变量?

private:关键字可以修饰成员变量和成员方法

注意:被private修饰的成员只能在本类中访问。

private int age;
public class NoNameDemo {

	public static void main(String[] args) {
		// 创建学生对象
		Student s = new Student();
		// 给成员变量赋值
		s.setAge(18); 
		s.name = "周十七";
		s.show();
		
		s.show ();
	}

}

/*
 * 定义一个学生类: 成员变量:name,age 成员方法: show()
 */
class Student {
	// 姓名
	String name;
	// 年龄
	private int age;

	// show()方法,显示所有成员变量值
	public void show() {
		System.out.println("姓名:" + name);
		System.out.println("年龄:" + age);
	}

	public void setAge(int a) {
		if (a < 0 || age > 120) {
			System.out.println("你给的年龄有问题");

		} else {
			age = a;
		}
	}
	
	
}
原则:

将不需要对外的内容都隐藏起来。

把属性隐藏,提供公共方式对其访问。

Private关键字

1、权限修饰符

2、可以修饰成员(成员变量和成员方法)

3、被其修饰的成员只在本类中才能访问

应用

1、把成员变量用private修饰

2、提供对应的getXxx(), setXxx();

public class PrivateDemo {
	public static void main(String[] args) {
		Demo d = new Demo();
		// System.out.println(d.num); 无法调用
		d.show();// 只能通过该类的方法调用
		// d.method(); 同理
		d.fucntion();

	}
}

class Demo {
	// int num = 10;
	// 用private修饰
	private int num = 10;

	public void show() {
		System.out.println(num);// 只能在本类中调用
	}

	private void method() {    //想调用它 必须建一个public 的方法来供外界调用
		System.out.println("method");
	}

	public void fucntion() {
		method();
	}

}
public class PrivateDemo {
	public static void main(String[] args) {
		Demo d = new Demo();
		d.setAge(18);
		System.out.println(d.getAge());
	}
}

class Demo {
	private int age;
	private String name;

	public int getAge() {
		return age;
	}

	public void setAge(int a) {
		age = a;
	}

	public String getName() {
		return name;
	}

	public void setName(String n) {
		name = n;
	}

}
this关键字

当前类的引用。就代表当前类的对象。 谁调用这个方法,在该方法内部的this就代表谁

	private int age;
	private String name;
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {//age 传给 当前类的age
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
this内存图解

在这里插入图片描述

构造方法

作用:给对象的数据进行初始化

格式: 方法名与类名 相同

​ 方法没有返回值类型

​ 没有具体的返回值

class Demo {
	public Demo(){
			System.out.println("这是一个构造方法");
	}
}

我们一直在使用构造方法却一直没有定义,从哪里来?

注意事项:

如果没有给出构造方法,系统将自动提供一个无参构造方法。

如果我们给出了构造方法,系统将不再提供。

注意:(如果还想使用无参构造方法,还需要自己给出)

public class PrivateDemo {
	public static void main(String[] args) {
        //创建对象
		Demo d = new Demo();//Demo()构造方法,

	}
}

给成员变量赋值:

1、setXxx()

2、构造方法

public class ConstructDemo {
	public static void main(String[] args) {
		Student s = new Student();
		s.show();
		System.out.println("-----------------------");
		//创建对象二
		Student s2 = new Student("周思琪");
		s2.show();
	}

}

class Student {
	private String name;
	private int age ;
	
	public Student() {
		System.out.println("这是无参构造方法");
	}
	
	public Student(int age) {
		System.out.println("这是构造方法重载");
	}
	
	public Student(String name) {
		System.out.println("这是带参数的构造方法");
		this.name = name;
	}
	
	public void show() {
		System.out.println(name+"........"+age);
	}

}

在这里插入图片描述

成员方法的分类

根据返回值:

​ 有明确返回值

​ 返回void类型

根据形式参数:

​ 无参数方法

​ 带参数

public class StudentDemo {
	public static void main(String[] args) {
		Student s = new Student();
		//调用无参无返回函数
		s.show();
		//调用无参有返回函数
		String result = s.getString();
		System.out.println(result);
		//带参无返回函数
		s.method("周思琪");
		//调用带参带返回函数
		String result2 =s.function("hello", "world");
		System.out.println(result2);
		
		
	}
}

class Student {
	public String getString() {
		return "helloworld";
		
	}
	
	public void show() {
		
	}
	
	public void method(String name) {
		
	}
	
	public String function(String s1,String s2) {
		return s1+s2;
		
	}
}
标准手机类练习

手机类:

成员变量: brand , price, color

构成方法 :无参构造

成员方法 :getXxx() / setXxx

public class Phone {
	//品牌
	private String brand;
	//价格
	private int price;
	//颜色
	private String color;
	
	//无参数构造函数
	public Phone() {
		
	
	}
	//getXxx()和setXxx()方法

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	

}
public class PhoneText {
	public static void main(String[] args) {
		//创建对象
		Phone p = new Phone();
		//给成员变量赋值
		p.setBrand("vivo");
		p.setColor("绿色");
		p.setPrice(1999);
		//获取值
		System.out.println(p.getBrand()+"--"+p.getColor()+"---"+p.getPrice());

	}
}
练习

001定义一个类Demo,定义一个数据和方法

变量定义在哪里?

​ 变量的范围越小越好,可以被及时回收

public class SunDemo {
	public static void main(String[] args) {
		//Demo d = new Demo();
		//System.out.println(d.sum());
		
		//Demo d = new Demo();
		//d.a = 10;
		//d.b = 20;
		//System.out.println(d.sum());

	}
}
//方式一参与操作数固定
/*class Demo{
	public int sum() {
		int a = 10;
		int b =20;
		int c = a+b;
		return c;
	}
	
}*/
//方式二 满足要求但是没有用面向对象思想
/*class Demo{
	public int sum(int a, int b) {
		return a+b;
	}
}*/
//方式三 成员变量a , b   但是这个变量和这个类没有关系不应该定义为成员变量
/*class Demo {
	int a;
    int b;
	public int sum(){
		return a+b;
	}
}*/

002定义一个长方形类,定义周长和面积的方法

长方形的类:

​ 成员变量:

​ 成员方法:

​ 求周长 : (长+宽)*2

​ 求面积: 长*宽

import java.util.Scanner;

public class SquareDemo {

	public static void main(String[] args) {
		// 创建键盘录入对象
		Scanner sc = new Scanner(System.in);

		System.out.println("请输入长方形的长:");
		int length = sc.nextInt();
		System.out.println("请输入长方形的宽:");
		int width = sc.nextInt();
		// 创建对象
		Square s = new Square();
		s.setLength(length);
		s.setWidth(width);

		System.out.println("长方形的周长是:"+s.getPerimeter());
		System.out.println("长方形的面积是:"+s.getarea());

	}

}

class Square {
	// 长方形的长
	private int length;
	// 长方形的宽
	private int width;

	public Square() {

	}
	// 仅仅提供setXxx即可

	public void setLength(int length) {
		this.length = length;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	// 求周长
	public int getPerimeter() {
		return (length + width) * 2;

	}

	// 求面积
	public int getarea() {
		return (length * width);
	}

}
static关键字

1、共享成员变量country

public class PersonDemo {
	public static void main(String[] args) {
		// 创建对象
		Person p1 = new Person("周思琪", 17, "中国");
		p1.show();
		Person p2 = new Person("周子豪", 17);
		p2.show();
		Person p3 = new Person("账号一", 17);
		p3.show();

	}
}

class Person {
	// 姓名
	String name;
	// 国籍
	String country;
	// 年龄
	int age;

	public Person() {

	}

	public Person(String name, int age) {
		this.age = age;
		this.name = name;
	}

	public Person(String name, int age, String country) {
		this.age = age;
		this.country = country;
		this.name = name;
	}

	public void show() {
		System.out.println("姓名" + name +" "+"年龄" + age +" "+"国籍" + country);
	}

}
public class PersonDemo {
	public static void main(String[] args) {
		// 创建对象
		Person p1 = new Person("周思琪", 17, "中国");
		p1.show();
		Person p2 = new Person("周子豪", 17);
		p2.show();
		Person p3 = new Person("账号一", 17);
		p3.show();

	}
}

class Person {
	// 姓名
	String name;
	// 国籍
	static String country;
	// 年龄
	int age;

	public Person() {

	}

	public Person(String name, int age) {
		this.age = age;
		this.name = name;
	}

	public Person(String name, int age, String country) {
		this.age = age;
		this.country = country;
		this.name = name;
	}

	public void show() {
		System.out.println("姓名" + name +" "+"年龄" + age +" "+"国籍" + country);
	}

}
		Person p1 = new Person("周思琪", 17, "中国");
		p1.show();
		Person p2 = new Person("周子豪", 17);
		p2.show();
		Person p3 = new Person("账号一", 17);
		p3.show();
		p3.country = "美国";
		p3.show();
		p2.show();
		p1.show();

	}
}
static 特点

1、随着类加载而加载

2、优先对象存在

3、被所有类的对象共享

​ 举例:咋们班的学生应该共用同一个班级编号。

​ 什么时候使用静态:

​ 如果某个人成员变量是被所有对象共享,那么它应该是静态的。

4、可以通过类名调用

​ 其实它本身也可以通过对象名调用。

​ 推荐使用类名调用。

静态修饰的内容一般称其为:与类相关的,类成员

public class asdasd {
	public static void main(String[] args) {
		Student s = new Student();
		//非静态
		System.out.println(s.num);
		//静态
		System.out.println(Student.num2);

	}
}
class Student{
	int num = 10;
	static int num2 =20;
}
注意事项:

001静态方法中是没有关键字的

理解:

​ 静态是随着类加载而加载,this是随着对象的创建而存在的。

​ 静态比对象先存在。

002静态方法只能访问静态的成员变量和静态的成员方法。

​ 静态方法:

​ 成员变量:只能访问静态变量

​ 成员方法:只能访问静态成员方法

​ 非静态方法:

​ 成员变量:可以是静态的,也可以是非静态的

​ 成员方法 :都可以

静态只能访问静态,非静态可以访问一切

静态变量和成员变量区别

所属不同

​ 静态变量 属于 类 也称类变量

​ 成员变量 属于 对象 也称实例变量(对象变量)

内存中位置不同

​ 静态变量存储于方法区的静态区

​ 成员变量存储于堆内存

内存出现时间不同

​ 静态变量随着类加载而加载,随着类消失而消失

​ 成员变量随着对象创建而存在,随着对象消失而消失

调用不同

​ 静态变量可以通过类名调用,也可以对象调用

​ 成员变量只能通过对象名调用

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!