标签:setter sys 答案 全局变量 变量 targe ati 每日一题 访问权限
成员变量指的是类里面定义的变量(field),局部变量指的是在方法里定义的变量。
成员变量无须显示初始化,系统会自动在准备阶段或创建该类的实例时进行默认初始化。
与成员变量不同,局部变量除了形参之外,都必须显示初始化。
命名规则:
当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配空间后,自动为成员变量赋初值。
当程序第一次使用某个类时,系统会为类变量分配内存空间并初始化,这个类变量是属于这个类的,并不属于实例。虽然我们还是能通过实例去访问这个类变量,但是通过任何实例访问的类变量都是同一个值,因为实际我们还是通过实例所属的类去访问的,为了避免语义混淆,建议访问类变量的时候通过类去访问,而不是实例。
系统不会为局部变量执行初始化,这意味着定义局部变量后,直到程序为这个变量赋初值,系统才会为局部变量分配内存,并将处置保存到内存中。
局部变量不属于任何类或实例,它总是保存在其所在方法的栈内存中。
重载的规则和方法重载差不多。特殊的一点是,如果一个构造器的执行体完全包含另一个构造器的执行体,则可在方法 B 中调用 方法 A。为避免调用时重复创建对象,需要使用 this 关键字,如下面代码:
1 public class Apple{ 2 public String name; 3 public String color; 4 public double weight; 5 public Apple(){} //无参数构造器 6 //两个参数构造器 7 public Apple(String name , String color){ 8 this.name = name; 9 this .color = color; 10 } 11 //三个参数构造器 12 public Apple(String name , String color , double weight){ 13 //通过另一个重载的构造器初始化代码,调用两个参数的构造器 14 this(name , color); 15 this.weight = weight; 16 } 17 }
PS:使用this调用另一个构造器只能在构造器中使用,而且必须作为构造器执行体的第一条语句。
封装就是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
良好的封装可以实现一下目的:
为了实现良好的封装,需要从两个方面考虑:
Java 的 4 个访问控制级别顺序由小到大:
private -> default(不加控制符) -> protected -> public
详细说明:
对于外部类而言,只能用 public 和默认,因为外部类没有处于任何类内部,也就没有其所在类的内部、所在类的子类这两个范围。public 修饰的外部类可以被所有类使用,默认控制权限的外部类只能被同一个包中的其他类使用。
PS:如果一个Java源文件里定义的所有类都没有 public 修饰,则这个 Java 源文件的文件名可以是一切合法的文件名;若有 public 类,必须和 public 类名一致。
一个良好封装的Person类:
1 public class person{ 2 //使用private修饰成员变量,将其隐藏起来 3 private String name; 4 private int age; 5 //提供方法来操作name成员变量 6 public void setName(String name){ 7 //执行合理性校验,用户名必须在2~6位之间 8 if (name.length() > 6 || name.length() < 2){ 9 System.out.println("您设置的人们不符合要求"); 10 return; 11 }else{ 12 this.name = name; 13 } 14 } 15 public String getName(){ 16 return this.name; 17 } 18 //提供方法来操作age成员变量 19 public void setAge(int age){ 20 //执行合理性,要求用户年龄在0-100之间 21 if (age > 100 || age < 0){ 22 System.out.println("您设置的年龄不合法"); 23 return; 24 }else{ 25 this.age = age; 26 } 27 } 28 public int getAge(){ 29 return this.age; 30 } 31 }
PS:如果一个 Java 类的每个实例变量都被使用 private 修饰,并为每个实例变量都提供了 setter 和getter方法,那么这就是一个符合 JavaBean 规范的类。
控制符使用的一些基本原则:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
我第一遍提交的时候发现速度排名有点慢,看了下评论才发现题目说这个数组是有序的,所以我的第一个答案是针对任何数组都可以删重。
1 class Solution { 2 public int removeDuplicates(int[] nums) { 3 HashMap<Integer , Integer> map = new HashMap<Integer , Integer>(); 4 for (int i = 0; i < nums.length; i++){ 5 if(map.get(nums[i]) == null) 6 map.put(nums[i] , 0); 7 } 8 int count = 0; 9 for(int i = 0; i < nums.length; i++){ 10 if(map.get(nums[i]) == 0){ 11 nums[count] = nums[i]; 12 count ++; 13 map.put(nums[i] , 1); 14 } 15 } 16 for(int i = count;i < nums.length; i++){ 17 nums[i] = 0; 18 } 19 return count; 20 } 21 }
第二个答案是针对题目所说的有序数组,速度超过99.2%的人。
1 class Solution { 2 public int removeDuplicates(int[] nums) { 3 int count = 1; 4 for(int i = 1; i < nums.length; i++){ 5 if(nums[i] > nums[count-1]){ 6 nums[count] = nums[i]; 7 count ++; 8 } 9 } 10 for(int i = count;i < nums.length; i++){ 11 nums[i] = 0; 12 } 13 return count; 14 } 15 }
标签:setter sys 答案 全局变量 变量 targe ati 每日一题 访问权限
原文地址:https://www.cnblogs.com/carlosouyang/p/10742299.html