變數類型、構造器、封裝以及 LeetCode 每日一題

来源:https://www.cnblogs.com/carlosouyang/archive/2019/04/20/10742299.html
-Advertisement-
Play Games

1.成員變數和局部變數 1.1成員變數和局部變數定義 成員變數指的是類裡面定義的變數(field),局部變數指的是在方法里定義的變數。 成員變數無須顯示初始化,系統會自動在準備階段或創建該類的實例時進行預設初始化。 與成員變數不同,局部變數除了形參之外,都必須顯示初始化。 命名規則: 一個類里不能定 ...


1.成員變數和局部變數

1.1成員變數和局部變數定義

成員變數指的是類裡面定義的變數(field),局部變數指的是在方法里定義的變數。

成員變數無須顯示初始化,系統會自動在準備階段或創建該類的實例時進行預設初始化。

與成員變數不同,局部變數除了形參之外,都必須顯示初始化。

命名規則:

  • 一個類里不能定義兩個同名的成員變數,即使一個是類變數,一個是實例變數;
  • 一個方法里不能定義兩個同名的方法局部變數,方法局部變數與形參也不能同名;
  • 同一個方法中不同代碼塊的代碼塊局部變數可以同名;
  • 如果先定義的代碼塊局部變數,後定義方法局部變數,前面定義的代碼塊局部變數與後面的方法局部變數可以同名。
  • Java 允許局部變數和成員變數同名,如果方法里的局部變數和成員變數同名,局部變數會覆蓋成員變數,如果需要在這個方法里引用被覆蓋的成員變數,可使用 this. (對於實例變數)或類名(對於類變數)作為調用者來限定訪問成員變數。

1.2成員變數初始化和記憶體

當系統載入類或創建該類的實例時,系統自動為成員變數分配記憶體空間,併在分配空間後,自動為成員變數賦初值。

當程式第一次使用某個類時,系統會為類變數分配記憶體空間並初始化,這個類變數是屬於這個類的,並不屬於實例。雖然我們還是能通過實例去訪問這個類變數,但是通過任何實例訪問的類變數都是同一個值,因為實際我們還是通過實例所屬的類去訪問的,為了避免語義混淆,建議訪問類變數的時候通過類去訪問,而不是實例。

1.3局部變數

系統不會為局部變數執行初始化,這意味著定義局部變數後,直到程式為這個變數賦初值,系統才會為局部變數分配記憶體,並將處置保存到記憶體中。

局部變數不屬於任何類或實例,它總是保存在其所在方法的棧記憶體中。

2 構造器

2.1 初始化

  • 當程式員調用構造器的時候,系統會先為對象分配記憶體空間,並完成預設初始化,這個對象已經產生了。接著構造器的執行體完成之後,這個對象作為構造器的返回值被返回。
  • 因為構造器一般需要被其它方法調用,因而常常把構造器設置成 public 許可權。極端情況下,如設置為 protected,主要用於被其子類調用;把其設置為 private,阻止其他類創建該類的實例。

2.2 構造器重載

重載的規則和方法重載差不多。特殊的一點是,如果一個構造器的執行體完全包含另一個構造器的執行體,則可在方法 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調用另一個構造器只能在構造器中使用,而且必須作為構造器執行體的第一條語句。

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類:

 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 規範的類。

控制符使用的一些基本原則:

  • 類里的絕大部夫成員變數應該用 private 修飾,只有一些 static修飾的、類似全局變數的成員變數,才考慮使用 public 修飾。除此之外,有些方法只用於輔助實現該類的其他方法,這些方法稱為工具方法,也應該用private修飾。
  • 如果某個類要做其它類的父類,該類里包含的大部分方法可能僅希望被其子類重寫,而不想被調用,則應該使用 protected 修飾這些方法。
  • 希望暴露出來給其他類自由調用的方法應該使用 public 修飾。因此類的構造器通過用 public 修飾從而允許在其他地方創建該類的實例。因為外部類通常都希望被其他類自由使用,所以大部分外部類用 public 修飾。

刪除排序數組中的重覆項(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]);
}

我第一遍提交的時候發現速度排名有點慢,看了下評論才發現題目說這個數組是有序的,所以我的第一個答案是針對任何數組都可以刪重。

 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 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ___setattr__魔方方法一定要註意防止無限遞歸當在此方法內部給屬性賦值的時候,那會調用此方法,又會重新賦值,無限重覆最後要歸於super是種解決方法。或者用dict方法。 1 class Recangle: 2 def __init__(self,width = 0,heigh = 0): ...
  • 在python3中爬蟲常用基本庫為urllib以及requests 本文主要描述urllib的相關內容 urllib包含四個模塊:requests——模擬發送請求 error——異常處理模塊 parse——關於URL處理方法的工具模塊 robotparser——通過識別網站robot.txt判斷網站 ...
  • 這裡 sqlproxy起到一個代理的作用,使用時無需關註 mysql和oracle的實現 ...
  • 什麼是優先順序隊列? 怎麼實現一個優先順序隊列? PriorityQueue是線程安全的嗎? PriorityQueue就有序的嗎? ...
  • 此程式在Windows10 CodeBlocks17.12環境下測試運行,其他編程環境未經測試! 作業需求↓↓↓↓↓↓ 運行效果圖如下 (codeblocks下載地址http://www.codeblocks.org/downloads/binaries) C++代碼 2019-04-20-20:3 ...
  • 2.1 變數是程式的基本組成單位 舉一個簡單的例子 2.2 變數的介紹 2.2.1 概念 變數相當於記憶體中一個數據存儲空間的表示,可以把變數看作是一個房間的門牌號,通過門牌號我們可以找到對應的房間,而通過變數名可以訪問到變數(值)。 2.2.2 變數使用的基本步驟 1) 聲明/定義變數(Scala要 ...
  • String:是對象不是原始類型. 為不可變對象,一旦被創建,就不能修改它的值. 對於已經存在的String對象的修改都是重新創建一個新的對象,然後把新的值保存進去. String 是final類, 不能被繼承. StringBuffer: 是一個可變對象,當對他進行修改的時候不會像String那樣 ...
  • 一、numpy和matplotlib庫的學習筆記 (1)numpy庫 1,從數值範圍創建數組 1 numpy.arange(start, stop, step, dtype)#參數分別為起始值,終止值,步長和數據類型 2.創建等間隔一位數組 1 np.linspace(start, stop, nu ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...