Java小白的幹貨鋪子(四)
一.靈活對應——多態性
多態是指對於一種服務功能,可以具有不同的實現方式,即多種形態。多態形象的描述了現實世界的復雜形態,使程序具有良好的擴展性。在繼承的基礎上,方法的重載是實現多態的方式之一。
重點:Object類的toString()與equals(Object obj)方法。
1. toString方法,其返回值為String類型,描述當前對象有關信息。如果直接打印某對象的引用,則默認調用這個對象的toString()方法,默認打印內容包含這個引用指向的內存地址。但是可以根據用戶自定義,重寫toString方法。
2. object類的equals方法為:
x.equals(y)
,當x和y指向同一地址返回ture,否則返回false。即:比較的是兩個對象的引用。
3. String類的equals()方法比較的是當前對象的字節符內容。
二.多態性是由封裝性和繼承性引出的面向對象的程序的另一個特征。
多態性的表現:
方法角度:方法的重載和重寫。
從對象的角度:分為兩種。
向上轉型:子類對象 ->父類對象(程序自動完成)
格式:父類 父類對象 = 子類實例
說明:向上轉型後,因為操作的是父類對象,所以無法找到在子類中定義的新方法;但是如果子類重寫了父類的某個方法,則調用的是重寫後的方法。
Student stu=new Student(); Person per=stu; // 向上轉型 per.say();
向下轉型:父類對象 -> 子類對象(必須明確指出要轉變的子類類型)
格式:子類 子類對象 = (目標對象)父類實例
說明:向下轉型前,先要向上轉型。
Person per=new Student(); // 向上轉型 Student stu=(Student)per; // 向下轉型 stu.learn();
intanceof關鍵字:在java中可以使用intanceof關鍵字判斷一個對象是否**屬於**一個類的實例。其中**屬於**兩層含義,一是類似“照妖鏡”的作用,看是否屬於某一個類;二是可以用於自己對象查看自己的類。
Person p=new Student(); System.out.println(p instanceof Person); // 判斷p是否是Person類型
final關鍵字:在java中聲明類、屬性和方法時,可以使用final來修飾。
註意:1.final修飾變量(成員變量或局部變量),則成為常量,只能賦值一次。
private final String NAME="張三";
2.final修飾方法,則該方法不能被子類重寫。
public final void walk(){ System.out.println("人用兩條腿走路~~~"); //final修飾方法 }
3.final修飾類,該類不能別繼承。
三.抽象類
定義:用abstract修飾的類即為抽象類。
格式:
abstract class 抽象類名{ }
1. 抽象類不能被實例化,必須被繼承。抽象方法必須被重寫,生成它的子類。由abstract修飾的方法就是抽象方法,抽象方法沒有方法體。
public abstract class Animal { private String name; private String food; public Animal(){ } public Animal(String name, String food) { this.name = name; this.food = food; } public abstract void eat(); // 抽象方法只聲明,不實現 }
2. 抽象類不一定要包含抽象方法,若類中包含了抽象方法,則該類必須被定義為抽象類。若子類也為抽象類,則可以不用重寫父類抽象方法。
// 如果子類也是一個抽象類,則可以不用重寫父類的抽象方法 public abstract class Tiger extends Animal{ public abstract void run(); }
四.接口
定義:是抽象類和常量值的定義集合。(沒有構造方法)接口是一種“標準”,“契約”。
從本質上講:接口是一種特殊的抽象類。這種抽象類只能包括常量和方法 的定義,而沒有變量和方法的實現。
聲明:
[public] interface interfaceName [extends listofsuperInterface]{
}
接口體:常量定義
type Name = value;
該常量被實現該接口的多個類共享,自帶public,static,final屬性。
/** * 飛翔接口 */ public interface Fly { public static final int SPEED=200; // 常量 public abstract void fly(); }
接口的實現類:與抽象類一樣,接口要使用也必須通過子類,子類通過implements關鍵字實現接口。
public class Kite implements Fly{ @Override public void fly() { System.out.println("風箏飛翔..."); } }
五.字符串相關類
String類
(1)String代表字符串類型,字符串的內容本身不可改變,字符串存在於“字符串常量池”中。
Java中字符串對象創建有兩種形式,一種為字面量形式,如String str = "Hello";,另一種就是使用new這種標準的構造對象的方法,如String str = new String("Hello");,這兩種實現其實存在著一些性能和內存占用的差別。這一切都是源於JVM為了減少字符串對象的重復創建,其維護了一個特殊的內存,這段內存被成為字符串常量池。
下圖展示使用new這種標準的構造對象的方法,在底層是怎麽實現的:
2.String類常用的方法
(1)public String(byte[] bytes)
使用平臺的默認字符集解碼,將字節數組轉換為字符串
(2)public String(byte[] bytes,Charset charset)
使用指定字符集解碼,將字節數組轉換為字符串
(3)public char charAt(int index)
根據索引位置獲取字符串中的某個字符
(4)public boolean contains(CharSequence s)
判斷當前對象代表的字符串是否包含參數字符串內容
(5)public boolean equals(Object anObject)
判斷字符串內容是否相同
(6)public byte[] getBytes()
將字符串轉換為字節數組
(7)public int indexOf(String str)
返回參數字符串在當前字符串中的索引位置
(8)public int lastIndexOf(String str)
從後往前找參數字符串,返回參數字符串在當前字符串中的索引位置
(9)public int length()
返回當前字符串的長度
(11)public String toLowerCase()
將字符串轉換為小寫
(12)public String toUpperCase()
將字符串轉換為大寫
(13)public char[] toCharArray()
將字符串轉換為字符數組
(14)public String substring(int beginIndex)
從beginIndex索引位置開始,到字符串末尾,截取字符串
(15)public String substring(int beginIndex,int endIndex)
從beginIndex索引位置開始,到endIndex-1,截取字符串
(16)public String trim()
返回一個字符串,這個字符串刪除了前導和尾隨空格
(17)public String[] split(String regex)
通過指定的正則表達式拆分字符串,將拆分後的結果作為一個字符串數組返回
3.StringBuffer:
Stringbuffer代表可變的字符序列。
工作原理:預先申請一塊內存,存放字符序列,如果字符序列滿了,會重新改變緩存區的大小,以容納更多的字符序列。是可變對象,這個是與String最大的不同(如果連續操作String對象,則會產生大量的“垃圾”,而且“斷開-連接”很頻繁。)
4.StringBuilder類:
StringBuilder和StringBuffer功能幾乎是一樣的,只是 StringBuilder是線程不安全的,StringBuffer是線程安全的。
六.內部類
定義:在類的內部定義另一個類。如果在類Outer的內部再定義一個類Inner,此時Inner就稱為內部類,而Outer則稱為外部類。
public class Outer { private String name="中國"; public void func(int x){ public class LocalInner{ public void method(){ System.out.println("局域內部類訪問外部類的屬性:"+name); System.out.println("局域內部類訪問包含其方法的參數"+x); } } } }
使用內部類的好處:(1)可以方便地訪問外部類的私有屬性。(2)減少了類文件編譯後的產生的字節碼文件的大小。
缺點:使程序結構不清楚。
成員內部類:(1)不能定義static變量。
(2)持有外部類的引用。
(3)格式(外部實例化成員內部類):外部類.內部類 內部類對象=外部類實例.new 內部類();
public class Outer { private String name="中國人"; // 成員內部類 class MemberInner{ public void method(){ System.out.println("內部類可以訪問外部類的私有屬性:"+name); } } public MemberInner getMemberInstance(){ return new MemberInner(); } }
2.靜態內部類:如果一個內部類使用static聲明,則此內部類就稱為靜態內部類,其實也相當於外部類。
可以通過外部類.內部類來訪問。 v靜態內部類不會持有外部類的引用,創建時可以不用創建外部類對象 v靜態內部類可以訪問外部的靜態變量,如果訪問外部類的非static 成員變量必須通過外部類的實例訪問 v外部實例化靜態內部類對象的格式:外部類.內部類 內部類對象= new 外部類.內部類();
public class Outer { private String name="中國"; private static int population=14; static class StaticInner{ public void method(){ System.out.println("靜態內部類直接訪問外部類的static屬性:"+population); Outer out=new Outer(); System.out.println("在靜態內部類中通過外部類對象訪問非static屬性:"+out.name); } } public static StaticInner getStaticInner(){ return new StaticInner(); } }
3.局部內部類:局域內部類是定義在一個方法中的內嵌類,所以類的作用範圍僅限於該方法中,而類生成的對象也只能在該方法中使用。局域內部類不能包含靜態成員。
public class Outer { private String name="中國"; public void func(int x){ class LocalInner{ public void method(){ System.out.println("局域內部類訪問外部類的屬性:"+name); System.out.println("局域內部類訪問包含其方法的參數"+x); } } new LocalInner().method(); // 在局域內部類所在的方法中實例化局域內部類對象,並調用其方法 } }
4.匿名內部類:如果一個內部類在整個操作中只使用一次的話,就可以定義為匿名內部類。
沒有名字的內部類 這是java為了方便我們編寫程序而設計的一個機制,因為有時候有的內部類只需要創建一個它的對象就可以了,以後再不會用到這個類,這時候使用匿 名內部類就比較合適。
public class TestAnonumity { public static void main(String[] args) { Jumping j=new Jumping(){ @Override public void jump() { System.out.println("跳..."); } }; j.jump(); } }
Java小白的幹貨鋪子(四)