变量类型、构造器、封装以及 LeetCode 每日一题
1.成员变量和局部变量
1.1成员变量和局部变量定义
成员变量指的是类里面定义的变量(field),局部变量指的是在方法里定义的变量。

成员变量无须显示初始化,系统会自动在准备阶段或创建该类的实例时进行默认初始化。
与成员变量不同,局部变量除了形参之外,都必须显示初始化。
命名规则:
- 一个类里不能定义两个同名的成员变量,即使一个是类变量,一个是实例变量;
 - 一个方法里不能定义两个同名的方法局部变量,方法局部变量与形参也不能同名;
 - 同一个方法中不同代码块的代码块局部变量可以同名;
 - 如果先定义的代码块局部变量,后定义方法局部变量,前面定义的代码块局部变量与后面的方法局部变量可以同名。
 - Java 允许局部变量和成员变量同名,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员变量,如果需要在这个方法里引用被覆盖的成员变量,可使用 this. (对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。
 
1.2成员变量初始化和内存
当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配空间后,自动为成员变量赋初值。
当程序第一次使用某个类时,系统会为类变量分配内存空间并初始化,这个类变量是属于这个类的,并不属于实例。虽然我们还是能通过实例去访问这个类变量,但是通过任何实例访问的类变量都是同一个值,因为实际我们还是通过实例所属的类去访问的,为了避免语义混淆,建议访问类变量的时候通过类去访问,而不是实例。
1.3局部变量
系统不会为局部变量执行初始化,这意味着定义局部变量后,直到程序为这个变量赋初值,系统才会为局部变量分配内存,并将处置保存到内存中。
局部变量不属于任何类或实例,它总是保存在其所在方法的栈内存中。
2 构造器
2.1 初始化
- 当程序员调用构造器的时候,系统会先为对象分配内存空间,并完成默认初始化,这个对象已经产生了。接着构造器的执行体完成之后,这个对象作为构造器的返回值被返回。
 - 因为构造器一般需要被其它方法调用,因而常常把构造器设置成 public 权限。极端情况下,如设置为 protected,主要用于被其子类调用;把其设置为 private,阻止其他类创建该类的实例。
 
2.2 构造器重载
重载的规则和方法重载差不多。特殊的一点是,如果一个构造器的执行体完全包含另一个构造器的执行体,则可在方法 B 中调用 方法 A。为避免调用时重复创建对象,需要使用 this 关键字,如下面代码:
 public class Apple{
     public String name;
     public String color;
     public double weight;
     public Apple(){} //无参数构造器
     //两个参数构造器
     public Apple(String name , String color){
         this.name = name;
         this .color = color;
     }
     //三个参数构造器
     public Apple(String name , String color , double weight){
         //通过另一个重载的构造器初始化代码,调用两个参数的构造器
         this(name , color);
         this.weight = weight;
     }
 }
PS:使用this调用另一个构造器只能在构造器中使用,而且必须作为构造器执行体的第一条语句。
3 隐藏和封装
3.1理解封装
封装就是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
良好的封装可以实现一下目的:
- 隐藏类的实现细节;
 - 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入逻辑控制,限制对成员变量的不合理访问;
 - 可进行数据检查,从而有利于保证对象信息的完整性;
 - 便于修改,提高代码的可维护性;
 
为了实现良好的封装,需要从两个方面考虑:
- 将对象的成员变量和实现细节隐藏起来,不允许外部直接访问和操作;
 - 把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作。
 
3.2使用访问控制符
Java 的 4 个访问控制级别顺序由小到大:
private -> default(不加控制符) -> protected -> public
详细说明:
- private(当前类访问权限):如果类里某一成员(变量、方法、构造器)使用 private 修饰,则这个成员只能在当前类的内部访问。显然这个控制符用于修饰成员变量最合适,可以把成员变量隐藏在类的内部。
 - default(包访问权限):default 访问控制的成员或外部类可以被相同包下的其他类访问
 - protected(子类访问权限):被 protected 控制符修饰的成员,既可以被同一个包中的其它类访问,也可以被不同包中的子类访问。通常情况下,如果用 protected 修饰一个方法,通常是希望其子类来重写这个方法。
 - public (公共访问权限):最宽松的访问级别,被 public 修饰的成员,可以被所有类访问,不管访问的类是否在一个包内,是否具有父子继承关系。
 

对于外部类而言,只能用 public 和默认,因为外部类没有处于任何类内部,也就没有其所在类的内部、所在类的子类这两个范围。public 修饰的外部类可以被所有类使用,默认控制权限的外部类只能被同一个包中的其他类使用。
PS:如果一个Java源文件里定义的所有类都没有 public 修饰,则这个 Java 源文件的文件名可以是一切合法的文件名;若有 public 类,必须和 public 类名一致。
一个良好封装的Person类:
 public class person{
         //使用private修饰成员变量,将其隐藏起来
         private String name;
         private int age;
         //提供方法来操作name成员变量
         public void setName(String name){
             //执行合理性校验,用户名必须在2~6位之间
             if (name.length() > 6 || name.length() < 2){
                 System.out.println("您设置的人们不符合要求");
                 return;
             }else{
                 this.name = name;
             }
         }
         public String getName(){
             return this.name;
         }
         //提供方法来操作age成员变量
         public void setAge(int age){
             //执行合理性,要求用户年龄在0-100之间
             if (age > 100 || age < 0){
                 System.out.println("您设置的年龄不合法");
                 return;
             }else{
                 this.age = age;
             }
         }
         public int getAge(){
             return this.age;
         }
 }
PS:如果一个 Java 类的每个实例变量都被使用 private 修饰,并为每个实例变量都提供了 setter 和getter方法,那么这就是一个符合 JavaBean 规范的类。
控制符使用的一些基本原则:
- 类里的绝大部夫成员变量应该用 private 修饰,只有一些 static修饰的、类似全局变量的成员变量,才考虑使用 public 修饰。除此之外,有些方法只用于辅助实现该类的其他方法,这些方法称为工具方法,也应该用private修饰。
 - 如果某个类要做其它类的父类,该类里包含的大部分方法可能仅希望被其子类重写,而不想被调用,则应该使用 protected 修饰这些方法。
 - 希望暴露出来给其他类自由调用的方法应该使用 public 修饰。因此类的构造器通过用 public 修饰从而允许在其他地方创建该类的实例。因为外部类通常都希望被其他类自由使用,所以大部分外部类用 public 修饰。
 
4 删除排序数组中的重复项(26题)
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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]);
}
我第一遍提交的时候发现速度排名有点慢,看了下评论才发现题目说这个数组是有序的,所以我的第一个答案是针对任何数组都可以删重。
 class Solution {
     public int removeDuplicates(int[] nums) {
         HashMap<Integer , Integer> map = new HashMap<Integer , Integer>();
         for (int i = 0; i < nums.length; i++){
             if(map.get(nums[i]) == null)
                 map.put(nums[i] , 0);
         }
         int count = 0;
         for(int i = 0; i < nums.length; i++){
             if(map.get(nums[i]) == 0){
                 nums[count] = nums[i];
                 count ++;
                 map.put(nums[i] , 1);
             }
         }
         for(int i = count;i < nums.length; i++){
             nums[i] = 0;
         }
         return count;
     }
 }
第二个答案是针对题目所说的有序数组,速度超过99.2%的人。
 class Solution {
     public int removeDuplicates(int[] nums) {
         int count = 1;
         for(int i = 1; i < nums.length; i++){
             if(nums[i] > nums[count-1]){
                 nums[count] = nums[i];
                 count ++;
             }
         }
         for(int i = count;i < nums.length; i++){
             nums[i] = 0;
         }
         return count;
     }
 }
变量类型、构造器、封装以及 LeetCode 每日一题的更多相关文章
- 【python】Leetcode每日一题-位1的个数
		
[python]Leetcode每日一题-位1的个数 [题目描述] 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 示例1 ...
 - 【python】Leetcode每日一题-删除有序数组中的重复项2
		
[python]Leetcode每日一题-删除有序数组中的重复项2 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不 ...
 - 【python】Leetcode每日一题-笨阶乘
		
[python]Leetcode每日一题-笨阶乘 [题目描述] 通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积.例如,factorial(10) = 10 * 9 * 8 * 7 * 6 ...
 - 【python】Leetcode每日一题-设计停车系统
		
[python]Leetcode每日一题-设计停车系统 [题目描述] 请你给一个停车场设计一个停车系统.停车场总共有三种不同大小的车位:大,中和小,每种尺寸分别有固定数目的车位. 请你实现 Parki ...
 - [LeetCode每日一题]88. 合并两个有序数组
		
[LeetCode每日一题]88. 合并两个有序数组 问题 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组. 初始化 n ...
 - LeetCode 每日一题「判定字符是否唯一」
		
我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 题目 ...
 - 【js】Leetcode每日一题-制作m束花所需的最少天数
		
[js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...
 - 【JavaScript】Leetcode每日一题-在D天内送包裹的能力
		
[JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...
 - 【js】Leetcode每日一题-完成所有工作的最短时间
		
[js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...
 
随机推荐
- 深度学习与自动驾驶领域的数据集(KITTI,Oxford,Cityscape,Comma.ai,BDDV,TORCS,Udacity,GTA,CARLA,Carcraft)
			
http://blog.csdn.net/solomon1558/article/details/70173223 Torontocity HCI middlebury caltech 行人检测数据集 ...
 - React 中阻止事件冒泡的问题
			
在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...
 - javascript入门篇(三)
			
字符串属性和方法 原始值字符串,如'liang', 没有属性和方法(因为他们不是对象). 原始值可以使用 JavaScript 的属性和方法,因为 JavaScript 在执行方法和属性时可以把原始值 ...
 - C# 添加Excel表单控件(Form Controls)
			
在Excel中,添加的控件可以和单元格关联,我们可以操作控件来修改单元格的内容,在下面的文章中,将介绍在Excel中添加几种不同的表单控件的方法,包括: 添加文本框(Textbox) 单选按钮(Rad ...
 - 设计模式系列1:单例模式(Singleton Pattern)
			
定义 保证一个类仅有一个实例,并提供一个该实例的全局访问点. --<设计模式GoF> UML类图 使用场景 当类只能有一个实例并且用户可以从一个众所周知的访问点访问它时. 创建一个对象需 ...
 - GIS之家资源
			
分享资源之arcgis软件系列 arcgis10.0(arcgis desktop以及arcgis server):下载 arcgis10.1(arcgis desktop以及arcgis serve ...
 - 关于微信JS-SDK 分享接口的两个报错记录
			
一.前提: 微信测试号,用微信开发者工具测试 二.简单复述文档: 1.引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/j ...
 - App瘦身、性能优化总结
			
App瘦身 资源瘦身 使用tinypng压缩PNG图片.视频可以通过 Final cut等软件进行分辨率压缩.音频则降低码率即可. 非必须资源文件可以放到自己服务器上 启动图使用 LaunchScre ...
 - docker 发布到私有docker registry
			
1.使用vs发布项目到文件夹: 2.在文件夹中新建dockerfile文件, 内容: FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-sli ...
 - nn.ConvTranspose2d的参数output_padding的作用
			
参考:https://blog.csdn.net/qq_41368247/article/details/86626446 使用前提:stride > 1 补充:same卷积操作 是通过padd ...