面向对象——封装

封装概述:

1、封装:隐藏事物的属性和实现细节,对外提供公共的访问方式。

2、封装的好处:

隐藏了事物的实现细节

提高了代码的复用性

提高了安全性

3、封装的原则:

隐藏事物的属性

隐藏事物的实现细节

对外提供公共的访问方式

private关键字

1、private单词:私有的

2、可以修饰的内容:

修饰成员变量

修饰成员方法

修饰构造方法

3、修饰之后的效果:

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

4、private关键字的注意事项;

private只是封装的一种体现形式

Getter和Setter

1、当属性被私有之后,外界无法直接访问,所以需要提供公共的访问方式,让外界可以间接的访问属性。对于当前类,就可以控制外界访问属性的方式。(我让你怎么访问,你就只能怎么访问)

2、一般提供get方法,获取成员变量的值、提供set方法,设置成员变量的值

变量访问原则和this关键字

1、变量访问的就近原则:

就近原则:当在访问某个变量名称的时候,会先寻找最近的该变量名称的定义,如果寻找到了,就使用该变量,如果没有找到,才到更远的位置寻找该变量名称的定义。

当局部变量和成员变量同名的时候,一定是先使用局部位置定义的变量,如果没有,才会使用成员位置定义的变量。

2、this关键字:

表示当前类型当前对象的引用

哪个来调用this所在的方法,this就代表哪个对象

作用:用于区分局部变量和成员变量同名的情况。使用this.属性名称的一定是成员变量,没有使用this.的变量,根据就近原则来确定使用哪个变量。

代码示例:

class Student {
    private String name;
    private int score;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void test(String[] args) {
        String name;
        name = "张三";//指的是局部变量name
    }
}

构造方法

构造方法概述

1、构造方法:构造函数,构造器,Constructor

2、作用:用于给对象中的成员变量赋值。在创建对象的同时,会自动调用构造方法,等对象创建完成的时候,对象中的成员变量就已经有指定的值了。

3、构造方法的定义格式:

 修饰符 方法名称(参数列表) {

  方法体
}

4、构造方法格式的说明:

1、构造方法的方法名称,必须和类名一模一样,连大小写都一样。
2、构造方法没有返回值类型,连void也没有
3、构造方法没有return语句,如果一定需要return语句,就写一个return;
	return后面不能跟 内容,加return没有实际的意义。

5、构造方法其他说明:

​ 1、构造方法不需要手动调用,由jvm虚拟机在创建对象的时候自动调用

​ 2、对象本身不能调用构造方法

​ 3、构造方法只调用一次。

构造方法的注意事项

1、构造方法可以是有参数的,也可以是没有参数的

​ 如果是没有参数的构造方法,外界无需传入任何的参数值,只能给成员变量赋固定值或者不赋值

​ 如果是有参数的构造方法,外界在调用构造方法的时候,需要传入实际的参数值,用于赋值给成员变量。

2、如果在类中没有定义任何的构造方法,那么系统会自动提供一个空参构造(空实现)

3、如果在类中手动定义了一个构造方法(无论是空参还是有参),系统都不再会提供任何的构造方法。

4、构造方法的重载:

在同一个类中,方法名相同,参数列表不同,与返回值类型无关

构造方法和set方法的比较

1、构造方法和set方法都是用于给成员变量赋值。二者都不希望外界直接访问私有成员变量,通过构造方法或者set方法,间接的访问私有变量。

2、区别:

构造方法是在创建对象的同时,由jvm自动调用执行,用于给属性赋值,只能执行一次

set方法是在创建对象之后,由对象手动调用执行,用于给属性修改值,可以调用多次

3、使用场景比较:

一般set方法使用更加灵活,使用更加频繁

构造方法,只能在创建对象的时候被自动调用一次,代码更加简洁。一旦对象创建成功,就不能继续使用构造方法修改成员变量的值。

静态

静态概述:

1、没有静态:如果某个类型的所有对象,都具有一个相同的属性值,比如2个对象的age都是23;

​ 那么这个属性值就没有必要在所有对象中,都存储一份。

​ 坏处:浪费内存空间;维护难度大,一旦需要修改,就得修改所有的对象。

无静态代码示例:

public class Test01 {
    public static void main(String[] args) {
        Actor a1 = new Actor();
        a1.name = "张三";
        a1.country = "中国";
        System.out.println(a1.name + "..." + a1.country);

        Actor a2 = new Actor();
        a2.name = "李四";
        a2.country = "中国";
        System.out.println(a2.name + "..." + a2.country);
        //二者都来自中国
    }
}
class Actor {
    String name;
    String country;
}

2、有静态的状态:如果某个类型的所有对象,都具有一个相同的属性值,那么就在这个属性的定义上,加一个static静态关键字。让该变量存储在方法区字节码的静态区中,避免了所有对象都存储相同数据的问题,节省了内存空间,将来维护容易(只需要修改一次)

有静态代码示例:

/**
 * 有静态代码示例
 */
public class Simple02 {
    public static void main(String[] args) {
        Actor1 a1 = new Actor1();
        a1.name = "张三";
        a1.country = "中国";
        System.out.println(a1.name + "..." + a1.country);//张三 中国

        Actor1 a2 = new Actor1();
        a2.name = "李四";
        a2.country = "中国";
        System.out.println(a2.name + "..." + a2.country);//李四 中国

        Actor1.country = "法国";
        System.out.println(a1.name + "..." + a1.country);//张三 法国
        System.out.println(a2.name + "..." + a2.country);//李四 法国
    }
}

class Actor1 {
    String name;
    static String country;//加上static关键字
}

静态变量的特点

1、静态的解释:static关键字

静态、静止的。静态变量不会随着对象的变化而变化

2、加载时机:

随着类的加载而加载。

静态变量随着类的加载进方法区,就直接在静态区给开辟了存储静态变量的内存空间

3、静态变量优先于对象而存在

4、静态变量被所有该类对象所共享

5、代码层面:可以使用类名直接调用,不需要使用对象名称。在不创建对象的前提下,仍然可以使用这个静态变量。建议使用类名来访问。

静态访问的注意事项

1、静态方法:在方法声明上,加上了static关键字的方法,就是静态方法

2、静态方法不能访问非静态的变量

原因:静态方法本身可以在没有创建对象的时候调用;非静态的变量只有在对象创建之后才存在。如果静态方法可以访问非静态的变量,那么就相当于在对象创建之前,就访问了对象创建之后的数据。明显不合理。

3、静态方法不能访问非静态的方法

原因:静态方法可以在没有创建对象的时候调用;非静态的方法可以访问非静态的变量。如果静态方法可以访问非静态的方法,就相当于静态方法间接的访问了非静态的变量

4、静态方法中不能存在this关键字

原因:this关键字表示本类当前对象。静态方法可以在对象创建之前调用。如果静态方法可以访问this关键字,相当于在创建对象之前,就使用了对象本身。矛盾。

5、总结:

静态不能访问非静态

静态变量和非静态变量的区别

1、概念上,所属不同:

非静态变量属于对象

静态变量属于类,类变量

2、内存空间不同,存储位置不同

非静态变量属于对象,所以存储在堆内存中

静态变量属于类,存储在方法区的静态区中

3、内存时间不同,生命周期不同

	非静态变量属于对象,所以生命周期和对象相同,随着对象的创建而存在,随着对象的消失而消失

	静态变量属于类,所以生命周期和类相同,随着类的加载

4、访问方式不同

​ 非静态变量只能使用对象名访问

​ 静态变量既可以使用对象访问,也可以通过类名访问:

类名.静态变量名

类名.静态方法名()

工具类

工具类的编写

1、工具类:在一个类中,没有维护什么数据,没有任何的成员变量,相当于是一个工具。类中就都是一些静态方法,快速的解决一些常见的问题。

2、名称:ArrayTool

3、作用:可以提供操作数据的各种方法

4、功能:

数组的遍历

获取数组的最大值

获取数组的最小值

数组元素反转

5、方法都是静态的,不需要创建对象;创建对象会浪费系统资源。希望控制不让创建对象。

方式:使用构造方法私有化

代码示例:

public class ArraysUtil

// 1、循环打印数组
public static void print(int[] arr) {
	for (int i = 0; i < arr.length; i++) {
		if (arr != null) {
			System.out.print(arr[i] + ",");
		}
	}
}

// 2、循环打印数组,一行打印指定个数的元素
public static void print(int[] arr, int number) {
	for (int i = 0; i < arr.length; i++) {
		System.out.print(arr[i] + ",");
		if ((i + 1) % number == 0) {
			System.out.println();// 换一行
		}
	}
}

// 3、将数组转成[元素1,元素2...]这种格式的字符串
public static String formatPrint(int[] arr) {
	if (arr == null)
		return "null";
	int iMax = arr.length - 1;// 如果iMax是-1 意味着数组长度是0
	if (iMax == -1)
		return "数组长度为0";
	StringBuilder b = new StringBuilder();//
	b.append('[');// 在最前方追加一个[
	for (int i = 0;; i++) {
		b.append(arr[i]);
		if (i == iMax) {// 满足条件 就退出
			return b.append(']').toString();
		}
		b.append(", ");
	}
}

// 4、将数组冒泡\或者其他算法排序(直接将原数组排序)
public static void sort(int[] arr) {
	for (int i = 0; i < arr.length - 1; i++) {
		for (int j = 0; j < arr.length - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int desk = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = desk;
			}
		}
	}
}

// 5、将数组冒泡\或者其他算法排序(不允许排形参的数组,需要直接返回一个排好序的新数组)
public  static int[] sortNew(int[] arr) {
	int arrNew[] = new int[arr.length];
	// 把源数组 内容赋值一份给 arrNew
	// arrNew = Arrays.copyOf(arr, arr.length);
	for (int i = 0; i < arrNew.length; i++) {
		arrNew[i] = arr[i];
	}

	for (int i = 0; i < arrNew.length - 1; i++) {
		for (int j = 0; j < arrNew.length - 1 - i; j++) {
			if (arrNew[j] > arrNew[j + 1]) {
				int desk = arrNew[j];
				arrNew[j] = arrNew[j + 1];
				arrNew[j + 1] = desk;
			}
		}
	}
	return arrNew;
}

// 6、比较两个数组的所有元素是否完全一致
public static boolean isEquals(int[] arr1, int[] arr2) {
	if (arr1 == arr2)// 地址相同 里面的数据肯定相同
		return true;
	if (arr1 == null || arr2 == null)
		return false;

	int length = arr1.length;
	if (arr2.length != length)
		return false;

	for (int i = 0; i < length; i++)
		if (arr1[i] != arr2[i])
			return false;

	return true;
}

// 7、计算数组的平均值
public static double avg(int[] arr) {
	double sum = 0;
	for (int i = 0; i < arr.length; i++) {
		sum += arr[i];
	}
	return sum / arr.length;
}

// 8、计算数组的最大值
public static int max(int[] arr) {
	int maxnumber = arr[0];// 数组第一个 为最大值
	for (int i = 1; i < arr.length; i++) {
		if (maxnumber < arr[i]) {
			maxnumber = arr[i];
		}
	}
	return maxnumber;
}

// 9、计算数组的最小值
public static int min(int[] arr) {
	int minnumber = arr[0];// 数组第一个 为最小值
	for (int i = 0; i < arr.length; i++) {
		if (minnumber > arr[i]) {
			minnumber = arr[i];
		}
	}
	return minnumber;
}

// 10、将一个数组的所有元素都反转(比如{5,4,8}变成{8,4,5})
public static int[] reverse(int[] arr) {
	int[] arrNew = new int[arr.length];
	for (int x = 0; x < arr.length; x++) {
		arrNew[x] = arr[arr.length - 1 - x];
	}
	return arrNew;
}

// 11、判断一个指定的数值在数组中是否存在
public static boolean isExits(int[] arr, int number) {
	boolean isTrue = false;
	for (int i = 0; i < arr.length; i++) {
		if (arr[i] == number) {
			return true;
		}
	}
	// 如果不存在
	return false;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值