Java學習筆記(9)
final關鍵字; (修飾符)
final關鍵字的用法:
- final關鍵字修飾一個基本類型的變量時,該變量不能重新賦值,第一次的值為最終的。
- final關鍵字修飾一個引用類型變量時,該變量不能重新指向新的對象。
- final關鍵字修飾一個函數的時候,該函數不能被重寫
- final關鍵字修飾一個類的時候,該類不能被繼承。
public class FinalTest { public static void main(String[] args) { // TODO Auto-generated method stub Circle c=new Circle(4.0); c.getArea();//c=new Circle(); } } class Circle { double r; final double pi=3.14; public Circle() {} public Circle (double r) { this.r=r; } public void getArea() { System.out.println("圓的面積是: "+r*r*pi); } }
調用方法時,傳遞的形式參數只是變量存儲的值,沒有把變量本身傳過去。
不同方法 上面的局部變量是相互獨立的,沒有任何的關系。
比如:
public class FinalTest { public static void main(String[] args) { // TODO Auto-generated method stub final Circle c=new Circle(4.0); test(c); //c=new Circle(); } public static void test(Circle c) { c=new Circle(); c.getArea(); } }
其中的test函數中的形式參數只是名字與上面的相同,其實沒有關系,也可以將形式參數名稱改為 Circle b,這樣不會混淆。
public class FinalTest { public static void main(String[] args) { // TODO Auto-generated method stub final Circle c=new Circle(4.0); test(c); //c=new Circle(); } public static void test(Circle b) { b=new Circle(5.0); b.getArea(); } }
結果為 圓的面積是: 78.5 而不是 50.24
常量的修飾符一般為:public static final
抽象類:
抽象類要註意的細節:
- 如果一個函數沒有方法體,那麽該函數必須要使用abstract修飾,把該函數修飾成抽象的函數
- 如果一個類出現了抽象的函數,那麽該類也必須使用abstract修飾
- 如果一個非抽象類繼承了抽象類,那麽必須要把抽象類的所有抽象方法實現
- 抽象類可以存在非抽象方法,也可以存在抽象的方法
- 抽象類可以不存在抽象方法
- 抽象類是不能創建對象的 因為抽象類是存在抽象方法的,如果能讓抽象類創建方法的話,那麽使用抽象的對象調用抽象的方法是沒有任何意義的
- 抽象類是存在構造函數的,其構造函數是提供給子類創建對象的時候初始化父類的屬性的。
public class Abstract { public static void main(String[] args) { // TODO Auto-generated method stub Dog d=new Dog("哈士奇","白色"); d.run(); Fish f=new Fish("金魚","紅色"); f.run(); } } abstract class Animal { String name; String color; public Animal(String name,String color) { this.name=name; this.color=color; } public abstract void run(); } class Dog extends Animal{ public Dog(String name,String color) { super(name,color); } public void run() { System.out.println(name+"四條腿跑得快"); } } class Fish extends Animal{ public Fish(String name,String color) { super(name,color); } public void run() { System.out.println(name+"搖尾巴遊得快"); } }
抽象類的應用場景:
- 我們在描述一類事物的時候,發現該種事物確實存在著某種行為,但是這種行為目前是不具體的,那麽我們可以抽取這種行為的聲明,但是不去實現該種行為,這時候這種行為我們稱為抽象的行為,我們就需要使用抽象類
抽象類的好處:強制要求子類一定要實現指定的方法。
常量的命名規範:全部字母大寫,單詞與單詞之間使用下劃線分分隔。
public class AbstractTest { public static void main(String[] args) { // TODO Auto-generated method stub Circle c=new Circle("圓形",4.0); c.getArea(); c.getLength(); Rect r=new Rect("矩形",3,4); r.getArea(); r.getLength(); } } abstract class MyShape{ String name; public MyShape() {} public MyShape(String name) { this.name=name; } public abstract void getArea() ; public abstract void getLength(); } //圓形 class Circle extends MyShape{ double r; public static final double PI=3.14; public Circle(String name,double r) { super(name); this.r=r; } public void getArea() { System.out.println(name+"的面積是:"+r*r*PI); } public void getLength() { System.out.println(name+"的周長是:"+2*PI*r); } } //矩形 class Rect extends MyShape{ int width; int height; public Rect(String name,int width,int height){ super(name); this.width=width; this.height=height; } public void getArea() { System.out.println(name+"的面積是:"+width*height); } public void getLength() { System.out.println(name+"的周長是:"+2*(width+height)); } }
abstract不能與以下關鍵字共同修飾一個方法:
- abstract不能與private共同修飾一個方法
- abstract不能與static共同修飾一個方法
- abstract不能與final共同修飾一個方法
值交換:
值傳遞:調用一個方法的時候,傳遞給方法的參數,實際上傳遞變量所存儲的值
重點:
- 形式參數是數據所屬函數的局部變量
- 不同函數的局部變量與局部變量是相互獨立,沒有任何的關系。
如果是不同的引用類型變量操作同一個對象,那麽肯定回影響到結果。
一個類最多只能由一個直接的父類。 Java是單繼承的
接口:
接口的定義格式:
interface 接口名{
}
接口要註意的事項:
- 接口是一個特殊的類
- 接口的成員變量默認的修飾符為: public static final 那麽也就是說接口中的成員變量都是常量
- 接口中的方法都是抽象的方法,默認的修飾符為public abstract
- 接口不能創建對象
- 接口是沒有構造方法的
- 接口是給類去實現使用的,非抽象類實現一個接口的時候,必須要把接口中的所有方法全部實現
實現接口的格式:
class 類名 implements 接口名{
}
public class Interface { public static void main(String[] args) { // TODO Auto-generated method stub PencilWithEraser p=new PencilWithEraser("2B鉛筆"); p.write(); p.remove(); } } //普通的鉛筆類 class Pencil{ String name; public Pencil() {} public Pencil(String name) { this.name=name; } public void write() { System.out.println(name+"沙沙的寫"); } } //橡皮接口 interface Eraser{ public void remove(); } //帶橡皮的鉛筆 class PencilWithEraser extends Pencil implements Eraser{ public PencilWithEraser(String name) { super(name); } public void remove() { System.out.println(name+"塗改"); } }
接口的作用:
- 拓展功能
- 定義約束規範
- 程序的解耦(程序設計要設計成低耦合) (從上往下越來越重要 這些功能)
例:
public class InterfaceTest { public static void main(String[] args) { // TODO Auto-generated method stub Student s=new Student("李四"); s.study(); MoneyStudent m=new MoneyStudent("張三"); m.study(); m.makeMoney(); } } //普通的學生類 class Student{ String name; public Student() {} public Student(String name) { this.name=name; } public void study() { System.out.println(name+"好好學習"); } } //接口 會掙錢是學生的拓展功能---定義在接口上 interface Money{ public void makeMoney(); } //會掙錢的學生 class MoneyStudent extends Student implements Money{ public MoneyStudent(String name) { super(name); } public void makeMoney() { System.out.println(name+"好好掙錢,然後交學費!"); } }
類與接口之間的關系:實現關系
類與接口要註意的事項:
- 非抽象類實現一個接口時,必須要把接口中的所有方法全部實現
- 抽象類實現一個接口時,可以實現也可以不實現接口中的方法
- 一個類可以實現多個接口
- 思考:為什麽Java不實現多繼承,而實現多接口呢?
接口與接口的關系:繼承關系
接口與接口之間的註意事項:
- 一個接口是可以繼承多個接口的
多態:一個對象具備多種形態(父類的引用類型變量指向了子類的對象或者是接口的引用類型變量指向了接口實現類的對象) 動物 a=new 狗();
多態的前提:必須存在繼承或者實現關系
多態要註意的細節:
- 多態情況下,子父類存在同名的成員變量時,訪問的是父類的成員變量
- 多態情況下,子父類存在同名的非靜態的成員函數時,訪問的是子類的成員函數
- 多態情況下,子父類存在同名的靜態的成員函數時,訪問的是父類的成員函數
- 多態情況下,不能訪問子類特有的成員
總結:
多態情況下,子父類存在同名的成員時,訪問的都是父類的成員,除了在同名的非靜態函數時,訪問的才是子類的
編譯看左邊,運行不一定看右邊
編譯看左邊:java編譯器在編譯的時候,會檢查引用類型變量所屬的類是否具備指定的成員,如果不具備馬上報錯
多態的應用:
1.多態用於形式參數類型的時候,可以接受更多類型的數據
2.多態用於返回值類型的時候,可以返回更多類型的數據
public class Kinds { public static void main(String[] args) { // TODO Auto-generated method stub Circle c=new Circle("圓形",4.0); print(c); Rect r=new Rect("矩形",3,4); print(r); } public static void print(MyShape s) { //MyShape s=new Circle(); 多態 s.getArea(); s.getLength(); } } abstract class MyShape{ String name; public MyShape() {} public MyShape(String name) { this.name=name; } public abstract void getArea() ; public abstract void getLength(); } //圓形 class Circle extends MyShape{ double r; public static final double PI=3.14; public Circle(String name,double r) { super(name); this.r=r; } public void getArea() { System.out.println(name+"的面積是:"+r*r*PI); } public void getLength() { System.out.println(name+"的周長是:"+2*PI*r); } } //矩形 class Rect extends MyShape{ int width; int height; public Rect(String name,int width,int height){ super(name); this.width=width; this.height=height; } public void getArea() { System.out.println(name+"的面積是:"+width*height); } public void getLength() { System.out.println(name+"的周長是:"+2*(width+height)); } }
結果為:
圓形的面積是:50.24
圓形的周長是:25.12
矩形的面積是:12
矩形的周長是:14
多態的好處:提高了代碼的拓展性
應用二:
public static void main(String[] args) { // TODO Auto-generated method stub Circle c=new Circle("圓形",4.0); print(c); Rect r=new Rect("矩形",3,4); print(r); MyShape m=getShape(1); //註意不能使用Rect或者Circle類型來接受,因為函數返回值類型為MyShape不能確定到底返回的是哪種 m.getArea(); m.getLength(); MyShape n=getShape(0); //調用了使用多態的方法,定義的變量類型 n.getArea(); n.getLength(); } //定義一個函數接受任意類型的圖形,然後計算任意圖形的周長及面積 public static void print(MyShape s) { //MyShape s=new Circle(); 多態 s.getArea(); s.getLength(); } //定義一個函數返回任意類型的圖形 public static MyShape getShape(int i) { if (i==0) { return new Circle("圓形",4.0); } else { return new Rect("矩形",3,4); } }
此時結果為:
矩形的面積是:12
矩形的周長是:14
圓形的面積是:50.24
圓形的周長是:25.12
Java學習筆記(9)