java封装

封装类及类的使用

封装的概念

  • 将东西包在一起,然后以新的完整形式呈现出来
    • 将方法和字段一起包装到一个单元中,单元以类的形式实现
  • 信息隐藏,隐藏对象的实现细节,不让外部直接访问到
  • 将数据和方法包装进类中,加上具体实现的隐藏(访问修饰符)共同被称作封装。其结果是一个同时带有特征和行为的数据类型

定义类,定义其属性、方法的过程称为封装类

定义类

class Student {}

class Student   //定义类
{
	int age;  //定义属性
	String name;
	double score;
	
	void introduce(){  //定义方法,同等于C语言的函数
		System.out.println("name:"+name+",age:"+age+",score:"+score);
	}
	void testFunc(){
		System.out.println("testFunc");
	}
}

类的使用

Student stu1 = new Student();

  • 通过一个类实例化一个对象
  • 类就只是一个模板,里面只有属性跟方法,里面具体的值是不清楚的
  • 类不能直接使用,不能直接访问变量,需要先实例化,就是需要申请一个空间,才能给属性赋值,使用类的方法
class Student
{
	int age;
	String name;
	double score;
	
	void introduce(){
		System.out.println("name:"+name+",age:"+age+",score:"+score);
	}
	void testFunc(){
		System.out.println("testFunc");
	}
}

public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student();//通过一个类实例化一个对象
		//类就只是一个模板,里面只有属性跟方法,里面具体的值是不清楚的
		//类不能直接使用,不能直接访问变量,需要先实例化,就是需要申请一个空间,才能给属性赋值,使用类的方法
		stu1.age = 20;
		stu1.name = "张三";
		stu1.score = 99.5;
		stu1.introduce();
	}
}

访问修饰符

规定类,成员属性,方法访问范围的关键字

信息隐藏是OOP最重要的功能之一,也是使用访问修饰符的原因

信息隐藏的原因包括

  • 对模块的任何实现细节所作的更改不会影响使用该模块的代码
  • 防止用户意外修改数据
  • 使模块易于维护和使用(大概类比为电脑配件)

访问修饰符

public:该类或非该类均可以访问

private:只有该类可以访问

protected:该类及其子类的成员可以访问,同一个包中的类也可以访问

默认:同一个包中的类也可以访问

位置private默认protectedpublic
同一个类
同一个包内的类
不同包内的子类
不同包并且不是子类

private 修饰符示例

class Student
{
	int age;
	String name;
	double score;
	
	private int sex;  //不能在类外通过实例对象访问属性变量,只能通过在本类里的函数访问
	
	void person(int finalsex){
		sex = finalsex;
	}
	
	void introduce(){
		System.out.println("name:"+name+" age:"+age+" sex:"+sex+" score:"+score);
	}
	void testFunc(){
		System.out.println("testFunc");
	}
}

public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student();//通过一个类实例化一个对象
		stu1.age = 20;
		stu1.name = "张三";
		stu1.score = 99.5;
		stu1.person(30);
		stu1.introduce();
		
	}
}

执行结果:
结果

属性封装的实现

  • 修改属性的可见性来限制对属性的访问
  • 为每个属性创建一对赋值方法(setter)和取值(getter)方法,用于公开对这些属性的访问接口
  • 在setter和getter方法中,根据需要加入对属性操作的原则

代码实现

class Student
{
	private int sex;
	
	public void setsex(int finalsex){  //赋值方法
		sex = finalsex;
	}
	
	public int getsex(){   //取值方法
		return sex;
	}
}

public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student();
		stu1.setsex(10);//赋值
		int a = stu1.getsex();//取值
		System.out.println("sex:"+a);
		
	}
}

执行结果:
结果

方法封装的目的

  • 隐藏方法实现细节(方法体),向外部提供公开接口(方法头),以供安全调用,简化调用,方便修改维护
  • 根据需要,可以私有化方法,以供内部使用
class Student
{
	private int age;
	
	private void myage(int myage){   //私有化方法,对属性修改
		age = myage;
	}
	
	public void setsex(int realage){   //赋值方法
		age = realage;
	}
	
	public int getsex(){               //取值方法
		myage(18);                   //调用私有化的方法对属性更改,让赋值方法改变的值发生自己想要的改变
		return age;
	}
}

public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student();
		stu1.setsex(36);
		System.out.println("sex:"+stu1.getsex());
		
	}
}

UML类图

UML是一种建模语言

  • 类的命名尽量要用应用领域中的术语,应用明确、无歧义,以利于相互交流和理解
  • 类的属性、操作中的可见性使用+、#、-分别表示public、protected、private

在这里插入图片描述

-表示private  
#表示protected 
~表示default,也就是包权限  
_下划线表示static  
斜体表示抽象 

构造方法

类构造方法的概念和作用

  • 构造方法负责对象初始化工作,为对象的属性赋合适的初始值
  • 创建对象时,其类的构造方法确保在用户操作对象之前,系统保证初始化的进行

构造方法的语法规则

  • 构造方法名与类名一致
  • 没有返回类型
  • 方法实现主要为字段赋初值

构造方法的调用

  • 构造方法的调用很特别:new操作符(实例化对象时,自动被调用)

Java系统保证每个类都有构造方法

Student(){}  
Java系统保证每个类都有构造方法,会默认添加这个方法
java语言中,方法是可重载的,类比C语言中函数名一样,参数列表不同,在C语言中不允许
class Student
{
	int age;
	String name;
	double score;
	
	Student(){
		System.out.println("构造方法一被调用");
	}  
	//Java系统保证每个类都有构造方法,会默认添加这个方法
	//java语言中,方法是可重载的,类比C语言中函数名一样,参数列表不同,在C语言中不允许
	
	Student(int newage,String newname){
		System.out.println("构造方法二被调用");
		age = newage;
		name = newname;
	}
	Student(int newage,String newname, double newscore){
		System.out.println("构造方法三被调用");
		age = newage;
		name = newname;
		score = newscore;
	}
}

public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student();
		Student stu2 = new Student(20,"wang");
		Student stu3 = new Student(18,"zhang",56.8);
		
	}
}

执行结果:
结果

this关键字

this关键字特点

  • 在类的方法中,使用this关键字代表的是调用此方法的对象的引用

      System.out.println(this.name);
    
class Student
{
	int age;
	String name;
	double score;
	void testThis(){
		System.out.println(this.name);
	}
	Student(int newage,String newname, double newscore){
		System.out.println("构造方法被调用");
		age = newage;
		name = newname;
		score = newscore;
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.testThis();
	}
}

执行结果:
结果

  • this可以看做是一个变量,它的值是当前对象的引用

      Student stutmp = null;
      stutmp = this;
      System.out.println(stutmp.age);
    
class Student
{
	int age;
	String name;
	double score;
	void testThis(){
		Student stutmp = null;
		stutmp = this;
		System.out.println(stutmp.age);
	}
	Student(int newage,String newname, double newscore){
		System.out.println("构造方法被调用");
		age = newage;
		name = newname;
		score = newscore;
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.testThis();
	}
}

执行结果:
结果

  • 使用this可以处理方法中的成员变量和形参同名的问题

      Student(int age,String name, double score){
      System.out.println("构造方法被调用");
      this.age = age;
      this.name = name;
      this.score = score;
      }
    
class Student
{
	int age;
	String name;
	double score;
	void testThis(){
		Student stutmp = null;
		stutmp = this;
		System.out.println(stutmp.score);
	}
	Student(int age,String name, double score){
		System.out.println("构造方法被调用");
		this.age = age;
		this.name = name;
		this.score = score;
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.testThis();
	}
}
  • 当在方法内需要用到调用到该方法的对象时,就可以用this

  • 在类的构造方法中可以调用this([参数列表])来调用该类的指定构造方法

    • 在类实例化调用类里的构造方法的时候,this()只能放在开头,调一次

    • this()不带参数的调用

class Student
{
	int age;
	String name;
	double score;
	void testThis(){
		Student stutmp = null;
		stutmp = this;
		System.out.println(stutmp.score);
	}
	Student(){
		System.out.println("构造方法一被调用");
	}
	Student(int newage,String newname){
		System.out.println("构造方法二被调用");
		age = newage;
		name = newname;
	}
	Student(int age,String name, double score){
		this();
		System.out.println("构造方法三被调用");
		this.age = age;
		this.name = name;
		this.score = score;
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.testThis();
	}
}

执行结果:
结果

this(23,“wang”)带参数的调用

class Student
{
	int age;
	String name;
	double score;
	void testThis(){
		Student stutmp = null;
		stutmp = this;
		System.out.println(stutmp.score);
	}
	Student(){
		System.out.println("构造方法一被调用");
	}
	Student(int newage,String newname){
		System.out.println("构造方法二被调用");
		age = newage;
		name = newname;
	}
	Student(int age,String name, double score){
		this(23,"wang");
		System.out.println("构造方法三被调用");
		this.age = age;
		this.name = name;
		this.score = score;
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.testThis();
	}
}

执行结果:
结果

static关键字的特点

  • 用来修饰类的成员——修饰成员变量的称为类变量(静态变量)

      Student.data = 20; //靠static关键字修饰变量,可以通过Student.data = 20;这样访问
    
class Student
{
	private int age;  //隐藏了的,在main里不能 stu1.age = 10;这样直接访问,需要在类里做个赋值,取值方法,在来操作
	String name;
	double score;
	static int data;
	
	Student(int age,String name, double score){
		this.age = age;
		this.name = name;
		this.score = score;
	}
	void introduce(){
		System.out.println("name:"+name+",age:"+age+",score:"+score);
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.score = 10;
		
		Student.data = 20;//靠static关键字修饰变量,可以通过Student.data = 20;这样访问

	}
}
  • 修饰成员方法称之为类方法(静态方法)

    • 加了static修饰符的方法调用:
public class Test1 {
	public static void main(String[] args) {		
		System.out.println("ret="+add(2,4));
	}
	static int add(int a,int b){
		return a+b;
	}
}
  • 不加static修饰符的方法调用:
public class Test1 {
	public static void main(String[] args) {
		Test1 t = new Test1(); 	
		System.out.println("ret="+t.add(2,4));
	}
	int add(int a,int b){
		return a+b;
	}
}
  • 当类被加载的时候就会被加载,优先于对象的存在

  • 用来修饰语句块——称之为静态代码块,先于构造方法之前执行,只会执行一次,用来对静态成员做初始化。

      static{
      	System.out.println("静态代码块");
      	data = 100;
      }
    
class Student
{
	private int age;  //隐藏了的,在main里不能 stu1.age = 10;这样直接访问
	String name;
	double score;
	static int data;
	
	Student(int age,String name, double score){
		System.err.println("构造方法");
		this.age = age;
		this.name = name;
		this.score = score;
	}
	static{
		System.out.println("静态代码块");
		data = 100;
	}
	void introduce(){
		System.out.println("name:"+name+",age:"+age+",score:"+score);
	}
}
public class Test1 {
	public static void main(String[] args) {
		Student stu1 = new Student(18,"zhang",56.8);
		stu1.score = 10;
		
		Student.data = 20;//靠static关键字修饰变量,可以通过Student.data = 20;这样访问
		
		System.out.println("ret="+Student.data);
	}
}

执行结果:

结果

  • 调用的时候可以直接通过类名.成员来进行访问

      Student.data = 20;
    

注意:

  • 静态方法中只能访问外部的静态成员

使用案例

class Student
{
	String name;
	static int data;
	
	static void test{
		System.out.println(data);
	}
}

错误使用案例

class Student
{
	String name;
	static int data;
	
	static void test{
		System.out.println(name);
	}
}
  • 静态方法中不能出现this关键字

方法的重载

多数程序设计要求为每个方法(函数)提供一个独一无二的方法名,不存在方法重载的概念,但在Java中,规定方法签名是解析方法的规则而不是方法名,为为方法重载开创了条件。

方法重载使得在一个类中,方法名相同而参数列表不同的方法可同时存在,代表相似的行为或功能。

public class Test1 {
	public static void main(String[] args) {
		int i = 10;
		char c = 'z';
		String str = "hello";
		System.out.println(i);
		System.out.println(c);
		System.out.println(str);
	}
}

执行结果:
结果

重载overload概念:同一个类中,同名不同参数的方法称为重载方法
注意:仅有返回值不同的方法不能称为重载

包(package)

打包的意义

  • 标准Java库是有一系列包组成,包括Java.lang java.util java.net等等。
  • 标准Java包就是层次型包结构,就如同硬盘上嵌套的子目录一样,我们可以使用嵌套层次结构来组织包。
  • Java的包是为了更好的规划代码,防止命名冲突和混乱,所以Java出现了打包机制。
  • 当把类组织起来放进一个包内之时,也就给包中的成员赋予了相互访问的权限,您就拥有了该包内的程序代码
  • 包访问权限把类聚集在一个包中这一做发提供了意义和理由

包的命名

为保证包名唯一性,所以在给包命名时一般使用互联网公司域名倒置来命名。

一个类可以使用同一个包中的所有类

一个类可以使用其它包中的所有公开类

怎么使用其它包中的公开类

  • 在每个类签名加上完整包名,例如:
java.util.Date today = new java.util.Date();
  • 更简洁更通用的方式:使用import语句来导包(eclipse Ctrl+Shift+o)
import java.util.Date;
...........
Date today = new Date();
  • 可以import特定类,也可以导入整个包,通过在源代码文件的顶部(在打包语句后)使用import语句来实现import java.util.*;

代码测试

com.yang.learn

Test.java

package com.yang.learn;

public class Test {
	public static void main(String[] args) {
		Demo dm = new Demo();
		dm.age = 20;
		dm.printfdata();
		com.yang.use.Demo dm2 = new com.yang.use.Demo();
		dm2.name = "zhang";
		dm2.printfinfo();
	}
}

Demo.java

package com.yang.learn;

public class Demo {
	int age;
	void printfdata(){
		System.out.println("同一个包里的age="+age);
	}
}

com.yang.use

Demo.java

package com.yang.use;

public class Demo {
	public String name;
	public void printfinfo()
	{
		System.out.println("不同包里的name="+name);
	}
}

执行结果:
结果

import com.yang.use.Demo1;
应用不同包里的类,不同包里,同包里的类名不要命名成样的

Test.java

package com.yang.learn;
import com.yang.use.Demo1;

public class Test {
	public static void main(String[] args) {
		Demo dm = new Demo();
		dm.age = 20;
		dm.printfdata();
		Demo1 dm2 = new Demo1();
		dm2.name = "zhang";
		dm2.printfinfo();
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值