日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java4】实例初始化,类初始化,/接口,多态,final/static,权限修饰符/native

發布時間:2024/4/24 java 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java4】实例初始化,类初始化,/接口,多态,final/static,权限修饰符/native 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1.實例初始化過程:有幾個構造器,就會有幾個實例初始化方法
  • 2.實例初始化和類初始化結合:先類(靜態)后實
  • 3.接口:只有abstract可省
    • 3.1 鳥類案例:Flyable相當于父類的一個補丁,因為有的鳥會飛,有的鳥不會飛
    • 3.2 繼承(extends)和實現(implements):extends B,C錯
  • 4.多態:和屬性無關,只說方法
    • 4.1 多態弊端:用instanceof 避免
    • 4.2 多態應用:USB相當于animal抽象類改為接口,里面connect是抽象方法
  • 5.final:final只有get方法
  • 6.static:修飾的成變不進堆
  • 7.四大權限修飾符:記住中間兩個本包,ppdp
  • 8.native:調用C/C++


1.實例初始化過程:有幾個構造器,就會有幾個實例初始化方法

package com.atguigu.test01.block; /** 1、類的成員:* (1)屬性:成員變量* (2)方法:成員方法* (3)構造器* (4)代碼塊分為如下:非靜態代碼塊, 靜態代碼塊(后面講,和static一起說)* * 2、非靜態代碼塊* (1)聲明的格式:* 【修飾符】 class 類名{* {* 非靜態代碼塊;* }* }* (2)非靜態代碼塊中的代碼什么時候執行? 在“每次”創建對象的時候執行,比構造器早執行。* (3)實例初始化過程:創建對象時,為對象進行初始化的操作,如下【1】和【2】按代碼先后,反正【3】最后。* 【1】為成員變量顯式賦值 【2】執行非靜態代碼塊 【3】執行構造器* * Java編譯器會把這三個部分的代碼,合成一個叫做<init>(【形參列表】)(在.class中)實例初始化方法* 即編譯后的.class字節碼信息中,是沒有構造器這個概念。 */ public class TestBlock {public static void main(String[] args) { Demo d1 = new Demo();//調用無參構造,本質上是調用<init>()實例初始化方法Demo d2 = new Demo("atguigu");//調用有參構造,本質上是調用<init>(形參列表)實例初始化方法} }class Demo{{System.out.println("非靜態代碼塊1");} private String str = assign();//調用方法,來為str進行顯式賦值public Demo(){System.out.println("無參構造");}public Demo(String str){this.str = str;System.out.println("有參構造");}{System.out.println("非靜態代碼塊2");}public String assign(){System.out.println("assign方法");return "hello";} }

如下的線上面是d1實例初始化過程,都是構造排最后。

package com.atguigu.test01.block;public class TestInit {public static void main(String[] args) {/*Son s = new Son();父類的無參構造(運行結果)子類的無參構造*/ /*Son s2 = new Son("atguigu");父類的無參構造子類的有參構造1*/ Son s3 = new Son("atguigu", 10);/*父類的無參構造子類的有參構造1子類的有參構造2*/} } class Father{public Father(){System.out.println("父類的無參構造");} } class Son extends Father{private String str;private int num; public Son(){//隱含了super(); 子類的構造器中一定會調用父類的構造器,默認調用父類的無參構造System.out.println("子類的無參構造");} public Son(String str){//隱含了super()this.str = str;System.out.println("子類的有參構造1");}public Son(String str,int num){this(str); //間接調用父類無參構造this.num = num;System.out.println("子類的有參構造2");} } package com.atguigu.test01.block; /** super()或super(實參列表)之前說的是調用父類的構造器,其實是調用父類對應的實例初始化方法* super()或super(實例列表)之前說的是在子類構造器的首行,其實是在子類實例初始化方法的首行*/ public class TestInit2 {public static void main(String[] args) {Zi z = new Zi();//312645 //先是super()} } class Fu{private String strFu = assignFu();{System.out.println("(1)父類的非靜態代碼塊");}public Fu(){System.out.println("(2)父類的無參構造");}public String assignFu(){System.out.println("(3)父類的assignFu()");return "fu";} }//1111111111111111111111111111111111111111111111111111111111111111111111111111 class Zi extends Fu{private String strZi = assignZi();{System.out.println("(4)子類的非靜態代碼塊");}public Zi(){//super() ==>調用父類的實例初始化方法,而且它在子類實例初始化方法的首行。//有extends先調用構造器System.out.println("(5)子類的無參構造");} public String assignZi(){System.out.println("(6)子類的assignZi()");return "zi";} } package com.atguigu.test01.block;public class TestInit3 {public static void main(String[] args) {Er r = new Er();//612645,因為子類重寫了assign(),所以3忽略 // Ba b = new Ba(); //312} } class Ba{private String str = assign();{System.out.println("(1)父類的非靜態代碼塊");}public Ba(){System.out.println("(2)父類的無參構造");}public String assign(){System.out.println("(3)父類的assign()");return "ba";} } class Er extends Ba{private String str = assign();{System.out.println("(4)子類的非靜態代碼塊");}public Er(){//super() ==>調用父類的實例初始化方法,而且它在子類實例初始化方法的首行,有extends先調用構造器System.out.println("(5)子類的無參構造");} public String assign(){System.out.println("(6)子類的assign()");return "er";} } package com.atguigu.homewok.test06; /** 實例初始化的過程:* (1)父類的實例初始化* <init>(){* x = 10;//父類的x* this.print();//子類的print,因為this代表的是正在創建的子類對象,而子類重寫了print,所以是子類的print。System.out.println("Son.x = " + x);//子類的x 沒有賦值x=0x = 20;//父類的x* }* * (2)子類的實例初始化* <init>(){* x = 30;//子類的x* this.print();//子類的print。System.out.println("Son.x = " + x);//子類的x 已經賦值x=30x = 40;//子類的x* }*/ public class Test06 {public static void main(String[] args) {Father f = new Son(); //先父類構造再子類構造System.out.println(f.x);//編譯時是Father類型,訪問Father中的x x=20(屬性看編譯時即左類型)} }class Father{int x = 10;public Father(){this.print();x = 20;}public void print(){System.out.println("Father.x = " + x);} }class Son extends Father{int x = 30;public Son(){this.print();x = 40;}public void print(){System.out.println("Son.x = " + x);} }

package com.atguigu.homewok.test07; /**(1)Test07類的初始化* <clinit>(){* int x = 5;//局部變量x--;//局部變量 x=4* Test07.x--;//靜態變量 x = -1* }**(2)執行main方法* System.out.println("x=" + x);//靜態變量 -1* z--;//靜態變量 z=-1* method();* y = z++ + ++z;//靜態變量 ,加載為準 *《1》先加載z的值“-1” //《2》z自增,z=0 《3》z自增 z =1《4》加載z的值“1” 《5》求和 “-1” + “1” = 0 《6》把0賦值給y y=0* System.out.println("result:" + (z + y + ++z));*《1》加載z的值“1” 《2》加載y的值"0" 《3》z自增 z=2 《4》加載z的值“2” 《5》求和 “1” + “0” + “2”*/ public class Test07 {static int x, y, z;//類變量,靜態變量,成員變量 默認值0static {int x = 5;//局部變量x--;//局部變量}static {x--;//靜態變量}public static void main(String[] args) {System.out.println("x=" + x);//靜態變量z--;//靜態變量method();System.out.println("result:" + (z + y + ++z));//靜態變量}public static void method() {y = z++ + ++z;//靜態變量} }

package com.atguigu.homewok.test08; /** 1、Base b1 = new Base();* 父類的實例初始化,和子類無關* <init>(){* method(100);* System.out.println("base : " + i); base:100* }* * 2、Base b2 = new Sub();*(1) 父類的實例初始化* <init>(){* method(100);//執行了子類重寫的method() //重要!!!* System.out.println("sub : " + j); sub:100* }*(2)子類的實例初始化* <init>(){* super.method(70);* System.out.println("base : " + i); base:70* }*/ public class Test08 {public static void main(String[] args) {Base b1 = new Base();Base b2 = new Sub();} }class Base {Base() {method(100);}public void method(int i) {System.out.println("base : " + i);} }class Sub extends Base {Sub() {super.method(70);}public void method(int j) {System.out.println("sub : " + j);} }

package com.atguigu.homewok.test09; // 考了兩個內容:final,方法的參數傳遞機制 public class Test09 {public static void main(String[] args) {Other o = new Other(); //o.i=0new Test09().addOne(o); //i=1System.out.println(o.i); //1} //o是引用數據類型,實參給形參的是地址值,那么形參修改了屬性,實參也會修改//o變量的值不能修改,不是說i的值不能修改public void addOne(final Other o){o.i++;} } class Other{public int i;//默認值0 } package com.atguigu.homewok.test02.day10; /** 實例初始化的過程:* (1)父類的實例初始化* <init>(){* System.out.print("1");* }* * (2)子類的實例初始化 * <init>(String name){* System.out.print("3");* father = new People(name + " F");//創建了一個父類的對象* 調用父類的<init>(String name){* System.out.print("2");* }* }*/ public class Test02 {public static void main(String[] args) {new Child("mike");} }class People {private String name;public People() {System.out.print("1");}public People(String name) {System.out.print("2");this.name = name;} }class Child extends People {People father;public Child(String name) {//隱含了super(),走了父類的無參構造System.out.print("3");father = new People(name + " F");}public Child() {System.out.print("4");} }

package com.atguigu.homewok.test07.day10; /** new A(new B());* (1)new B()* <init>(){* System.out.println("B");* }* *(2)new A(B的對象即B b)* <init>(B b){* this();* System.out.println("A");* System.out.println("AB");* }*/ public class Test07 {public static void main(String[] args) {new A(new B());} }class A {public A() {System.out.println("A");}public A(B b) {this();System.out.println("AB");} }class B {public B() {System.out.println("B");} }

package com.atguigu.homewok.test08.day10; /** (1)父類實例初始化* <init>(){* System.out.println("base");* method(100); //子類重寫了,執行子類的method //System.out.println("sub : " + j); sub:100* }* * (2)子類實例初始化* <init>(){* System.out.println("sub"); sub* super.method(70); //父類的method //System.out.println("base : " + i); base 70* }*/ public class Test08 {public static void main(String[] args) {Sub s = new Sub();} }class Base{Base(){method(100);}{System.out.println("base");}public void method(int i){System.out.println("base : " + i);} }class Sub extends Base{Sub(){//隱含了:super()super.method(70); //注意super.}{System.out.println("sub");}public void method(int j){System.out.println("sub : " + j);} }

2.實例初始化和類初始化結合:先類(靜態)后實

package com.atguigu.test04;public class TestInit {public static void main(String[] args) {Demo d = new Demo();//2631745} } class Demo{{System.out.println("(1)Demo的非靜態代碼塊1");}static{System.out.println("(2)Demo的靜態代碼塊1");}private static String info = assign();private String message = getMessage();static{System.out.println("(3)Demo的靜態代碼塊2");}{System.out.println("(4)Demo的非靜態代碼塊2");}public Demo(){System.out.println("(5)無參構造");}public static String assign(){System.out.println("(6)assign()方法");return "hello";}public String getMessage(){System.out.println("(7)getMessage()方法");return "msg";} } package com.atguigu.test04; /** (1)先完成父類的類初始化* (2)再完成子類的類初始化* (3)父類的實例初始化方法* (4)子類的實例初始化方法*/ public class TestInit2 {public static void main(String[] args) {DemoZi zi1 = new DemoZi(); //2,6,3/,9,13,10/,1,14,4,5/,8,14,11,12System.out.println("-------------------");DemoZi zi2 = new DemoZi();} } class DemoFu{{System.out.println("(1)Demo的非靜態代碼塊1");}static{System.out.println("(2)Demo的靜態代碼塊1");}private static String info = assign();private String message = getMessage(); //子類重寫了static{System.out.println("(3)Demo的靜態代碼塊2");}{System.out.println("(4)Demo的非靜態代碼塊2");}public DemoFu(){System.out.println("(5)無參構造");}public static String assign(){System.out.println("(6)assign()方法");return "hello";}public String getMessage(){System.out.println("(7)getMessage()方法");return "msg";} } class DemoZi extends DemoFu{{System.out.println("(8)");}static{System.out.println("(9)");}private static String info = assign();private String message = getMessage();static{System.out.println("(10)");}{System.out.println("(11)");}public DemoZi(){System.out.println("(12)");}public static String assign(){System.out.println("(13)");return "hello";}public String getMessage(){System.out.println("(14)getMessage()方法");return "msg";} }

3.接口:只有abstract可省


抽(abstract可省)/默(default不可省)。靜(static不可省,方片,類名/接口名.)/常。

類中只有final修飾要初始化,其他不需要。

package com.itheima04.constant; /* * 接口中的常量:1. 接口中的屬性沒有變量都是常量(一次賦值,終身不變)。默認用 public static final 修飾 * 2. static (靜態) : 可以接口名直接調用 * 3. final (最終): 用final修飾的屬性是常量,一次賦值,終身不變 * 4. 軟性規范: 常量名一般大寫 */ public class ConstantDemo {public static void main(String[] args) {System.out.println(A.I); //1System.out.println(Student.K); //2 //類名.調用因為static,不能修改因為final(釘子釘住了)System.out.println(Student.j); //0 //Student.i報錯,不是靜態不能類名.調用} } class Student{ //以下都不報錯int i; static int j;public final static int K = 2; } interface A{int I = 1;public static final int J = 2; }

3.1 鳥類案例:Flyable相當于父類的一個補丁,因為有的鳥會飛,有的鳥不會飛

package com.itheima05.bird;public class BirdDemo {public static void main(String[] args) {Sparrow sparrow = new Sparrow();sparrow.name = "杰克";sparrow.eat(); //杰克正在吃東西sparrow.fly(); //杰克正在撲騰Qq qq = new Qq();qq.name = "企鵝";qq.eat(); //企鵝正在吃東西} } class Bird{String name;int age;//alt+insert快捷鍵構造函數,但必須鼠標停在類中public Bird(){}public Bird(String name, int age) {this.name = name;this.age = age;}public void eat(){System.out.println(name + "正在吃東西");} }//11111111111111111111111111111111111111111111111111111111111111111111111 interface Flyable{void fly(); //抽象方法 } class Sparrow extends Bird implements Flyable{ //子類默認調用父類的空參構造@Overridepublic void fly() {System.out.println(name + "正在撲騰");} } class Qq extends Bird{ }

如下和上面無關。

public class TestInterfaceDefineAndUse {public static void main(String[] args) { // Flyable f = new Flyable();//接口不能直接創建對象的Flyable[] sky = new Flyable[3]; //存放接口的數組//數組的元素類型Flyable類型,是接口類型sky[0] = new Bird();//多態引用sky[1] = new Plane();sky[2] = new Kite(); for (int i = 0; i < sky.length; i++) {//數組的元素類型Flyable類型,是接口類型sky[i].fly();}} } interface Flyable{ // public static final long MAX_SPEED = 7900000;long MAX_SPEED = 7900000; // public abstract void fly();void fly(); } interface Jumpable{void jump(); } class Animal{ }//1111111111111111111111111111111111111111111111111111111111111111111 class Bird extends Animal implements Flyable,Jumpable {//重寫接口的抽象方法,實現接口的抽象方法@Overridepublic void fly() {System.out.println("小鳥振翅高飛");}@Overridepublic void jump() {System.out.println("雙腳跳");} }class Plane implements Flyable{@Overridepublic void fly() {System.out.println("靠發動機帶動飛行");} } class Kite implements Flyable{@Overridepublic void fly() {System.out.println("靠人放");} }//1111111111111111111111111111111111111111111111111111111111111111 interface A{void a(); } interface B{void b(); } interface C extends A,B{void c(); } class Impl implements C{ //必須重寫3個方法@Overridepublic void a() {}@Overridepublic void b() {}@Overridepublic void c() {} }




因為接口必須重寫抽象方法,吃草吃肉和J無關。

package com.itheima06.tedian; /* * 1. 如果兩個父接口存在相同 抽象方法。 解決: 子類隨便重寫一個即可 * 2. 如果兩個父接口存在相同 默認方法。 解決: 子類必須重寫這個默認方法 * 3. 如果兩個父接口存在相同 靜態方法, 常量。 子類什么都不用做,直接用 接口名調用 */ public class Demo02 {public static void main(String[] args) {J j = new J();j.method(); // 10 20} } interface H{public static final int NUMBER = 10; //常量void eat(); //抽象default void eat2(){ //默認//吃草}static void eat3(){ //靜態} } interface I{public static final int NUMBER = 20; void eat(); default void eat2(){ }static void eat3(){ } }//111111111111111111111111111111111111111111111111111111111111111111 class J implements H,I{ //H,I 是 J的父接口@Overridepublic void eat() {}@Overridepublic void eat2() {//不能帶上default//到底吃什么,子類重寫后說了算} void method(){System.out.println(H.NUMBER); //如下都是static,用接口.調用System.out.println(I.NUMBER);H.eat3();I.eat3();} }

3.2 繼承(extends)和實現(implements):extends B,C錯

package com.itheima06.tedian; /* * 1. 類繼承類: 只能單繼承,不能多繼承 class A extends B { } * 2. 類實現接口: 可以多實現,沒有接口與類之間關系 class A implements B,C...{ } * 3. 接口繼承接口: 可以多繼承 interface A extends B,C...{ } */ public class Demo03 {public static void main(String[] args) {} } interface M{void eat(); } interface L{void run(); } interface N extends M,L{ }class O implements N{ //1@Override public void eat() {}@Overridepublic void run() {} }class P implements M,L{ //2同1@Overridepublic void eat() {}@Overridepublic void run() {} }

package com.itheima06.tedian; /** 1. 一個類S 繼承類Q, 又實現接口R (而Q和R又有相同的方法)* 符合就近原則: 繼承類Q中的方法 * 2. (而Q和R又有相同的方法 : Q中方法不抽象 R方法抽象)* 那么子類不用重寫R中抽象方法。原理: 用Q中繼承過來的方法來 代替 抽象方法重寫*/ public class Demo04 {public static void main(String[] args) { S s = new S();s.eat(); //吃草} } abstract class Q{public void eat(){System.out.println("吃草");}public abstract void eat2();public void eat3(){ //不抽象,S類中不用重寫} } interface R{default void eat(){System.out.println("吃肉");}void eat2();void eat3(); } class S extends Q implements R{@Overridepublic void eat2() { //必須重寫抽象方法} } /*1. 任何一個類(除Object之外), 如果沒有顯示聲明繼承哪個,那么直接繼承Object2. 用類中繼承來的同名方法 代替 接口中的抽象方法重寫 */ interface T{boolean equals(Object obj); } class U implements T{ //class U extends Object implements T //Object有equals方法 }

4.多態:和屬性無關,只說方法

package com.itheima07.duotai; /* * java精髓: 接口和多態。多態:提高代碼擴展性(當需求改變的時候,代碼改的越少,擴展性越強) * 1. 含義: 一種行為卻展示出多種形態 * 2. 表述: 父類/父接口 引用 指向子類對象。 父類/父接口 引用調用方法,執行的是子類重寫的方法 * 3. 多態三要素,必要條件 * 1. 繼承 (類繼承,接口) * 2. 重寫 (方法重寫) * 3. 向上轉型 (父類引用指向子類對象) * * 向上轉型(默認成立的) * 1. 前提 : 基于繼承關系 * 2. 格式:父類類型 變量/引用 = new 子類類型(); * 3. 含義:子類對象 實際上 都可以說是 父類中一種實例即看到狗就說它是種動物 * * 為什么一定需要方法重寫? 編譯看左邊,運行看右邊 * 1. 運行的時候,子類對象會運行子類重寫的方法,無論左邊類型是父類/子類(Animal/Dog) * 2. 問題: 父類中定義的方法 沒有用,那為什么一定要寫? 是為了通過編譯 * 1. 編譯看左邊 * java代碼 -> .class文件 -> runtime * 編譯 運行 * (編譯器 : 不知道運行階段的事 即 右邊的事不關心) * 2. 運行看右邊:右邊的內容是在運行階段賦值給左邊 */ public class DuotaiDemo {public static void main(String[] args) { // Dog dog = new Dog(); //這是方法重寫不是多態 // dog.eat();//向上轉型 : 前提繼承。如下a是內存地址/變量/引用 即 父類引用指向子類對象Animal a = new Dog(); //多態的表現出來的特征:1.編譯類型與運行時類型不一致,2.方法重寫a.eat();// 一種行為eat,多種形態(什么形態.具體要取決是什么對象)。//打印出:狗在吃骨頭} }//11111111111111111111111111111111111111111111111111111111111111111 abstract class Animal{public void eat(){System.out.println("動物在吃飯");} } class Dog extends Animal{public void eat() {System.out.println("狗在吃骨頭");} } class Cat extends Animal{public void eat() {System.out.println("貓在吃魚");} }


如下通過編譯了,運行報錯(右邊true運行時才賦值給左邊)。

4.1 多態弊端:用instanceof 避免

如下是多態的好處。

如下不看注釋掉的,只需給method(new Dog())傳入實參,更簡便。

如上會出現問題:貓, 狗,狼 吃各自的東西。但如果是貓, 貓還會加餐吃 貓糧即add方法(如鉆石會員加個特效)。

如下是強制向下轉型弊端:method(new Dog())。

package com.itheima09.duotai3; /* * 多態的弊端:向上轉型(默認一定成功,向下轉型可能失敗)之后, 父類引用無法調用子類 特有 的方法(編譯看左邊) * 解決:向下轉型 也叫 強制類型轉換:子類類型 變量 = (子類類型)父類引用 * * 強制類型轉換是有可能失敗的 : ClassCastException(類轉換異常)。失敗條件: 對象實際上是A類型,硬要轉換成B類型 * 避免: 添加一個類型判斷:(boolean result = 變量 instanceof 類型)如果變量剛好是A類型, 返回true */ public class DuotaiDemo {public static void main(String[] args) {// 需求: 讓各種動物吃東西(早上讓貓吃,晚上讓狼吃),多態Animal a = new Cat(); //沒用methoda.eat(); //貓在吃魚Wolf w = new Wolf();method(w); //狼吃肉method(new Cat()); //貓在吃魚 貓加餐吃貓糧method(new Dog()); //狗在吃骨頭}//1111111111111111111111111111111111111111111111111111111111111111111111 public static void method(Animal a){a.eat(); boolean result = a instanceof Cat;if(result){Cat c = (Cat)a; //向下轉型c.add();}} } abstract class Animal{public abstract void eat(); } class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗在吃骨頭");} } class Cat extends Animal {@Overridepublic void eat() {System.out.println("貓在吃魚");}public void add(){System.out.println("貓加餐吃貓糧");} } class Wolf extends Animal{@Overridepublic void eat() {System.out.println("狼吃肉");} }

4.2 多態應用:USB相當于animal抽象類改為接口,里面connect是抽象方法

如下extend()相當于上面method(),USB usb相當于Animal a,usb.connect()相當于a.eat()。

package com.itheima10.computer;public class Computer { //主void open(){System.out.println("電腦開機了");}void close(){System.out.println("電腦關機了");}void extend(USB usb){//interface USB不能實例化,可以USB usb但不能調用時用new USB()傳入,new 子類傳入usb.connect();} }//11111111111111111111111111111111111111111111111111111111111111111111111 interface USB{ //補丁 //接口: 標準/規范 void connect(); //下定義 : 抽象方法 } class Mouse implements USB{ // 實現接口: 符合某種標準@Overridepublic void connect() {System.out.println("鼠標連接上了");} } class Keyboard implements USB{@Overridepublic void connect() {System.out.println("鍵盤連接上了");} } package com.itheima10.computer; import com.itheima10.computer.Computer;public class TestDemo {public static void main(String[] args) {Computer computer = new Computer();computer.open();computer.close();//如下不能寫成Computer m =new Mouse();因為不存在繼承關系,不是多態Mouse m = new Mouse();computer.extend(m); Keyboard k = new Keyboard();computer.extend(k); // k:USB usb = new Keyboard(); //usb可以實例化,因為Keyboard這個類實現了USB這個接口 } }

package com.atguigu.test02.polymorphism; /** 多態的應用:多態數組:數組的元素是父類的類型,實際存儲的是子類的對象,用這樣的數組就可以統一管理所有子類的對象。*/ public class TestUse1 {public static void main(String[] args) {//創建一個數組,可以存儲各種圖形的對象,包括圓對象,矩形對象,三角形對象...//Circle[] yuans = new Circle[3]; //這個數組存圓 //本態數組//Rectangle[] jus = new Rectangle[3]; //這個數組存矩形 Graphic[] all = new Graphic[3];//這個數組就可以存儲各種圖形的對象all[0] = new Circle(1.2); //左邊的元素all[0]是Graphic類型,右邊是子類圓對象Graphic g2 = new Rectangle(2, 4); //多態//左邊g2是Graphic,右邊是矩形對象,如下分開寫和上面一樣。all[1] = g2;all[2] = new Circle(4.2);//遍歷所有圖形的面積for (int i = 0; i < all.length; i++) {//執行哪個getArea()方法,要看all[i]中存儲的是哪個子類的對象System.out.println("面積:" + all[i].getArea());}} }//1111111111111111111111111111111111111111111111111111111111111111111111111111 class Graphic{ //Graphic圖形public double getArea(){return 0.0;//這句話沒有什么意義,只是為了保證語法} } class Circle extends Graphic{private double radius;public Circle(double radius) {this.radius = radius;} public double getArea(){ //重寫return 3.14 * radius * radius;} } class Rectangle extends Graphic{private double length;private double width;public Rectangle(double length, double width) {this.length = length;this.width = width;} public double getArea(){ //重寫return length * width;} }




接口是規范/標準,多態是拓展性。

5.final:final只有get方法

package com.itheima00.question; public class Demo01 {public static void main(String[] args) {// 繼承關系分為如下兩種:FuClass fc = new Zi(); //類繼承 FuIn fi = new Zi(); //接口實現 // 如上向上轉型,如下向下轉型 // 父類類型變量 instanceof 子類類型:用來判斷是不是繼承的// boolean result = fc instanceof String; //錯誤,因為fc和String沒有繼承關系 boolean result = fi instanceof Zi;//可以true,fc instanceof Zi也為true} } interface FuIn{ } class FuClass{ } class Zi extends FuClass implements FuIn{ } package com.itheima01.finald; /* * final:不可繼承(類)如String類很完美 不可重寫(方法) 不可修改(屬性) * 方法重寫的出現打破了類的封裝性, final修飾方法既保證了封裝,又保證了繼承 */ public class Demo01 {public static void main(String[] args) {C c = new C();c.eat(); //不能重寫但能繼承 //聯合聲明: ~~} } class B {public final void eat(){ //final 修飾方法可繼承,不是類。System.out.println("聯合聲明: ~~");} } class C extends B{ //C是B的發言人 }


如下i有默認初始值0,所以若final int j = 0,final寫了沒意義,主因D類使用時無法給j賦值。

解決如上問題還有如下構造器方法,但是需要刪除有漏洞的有參構造器。

如下無漏洞的有參構造器。

/* * 問題: 解釋一下都用final修飾,成員變量不給初始值會編譯報錯, 而局部變量不給初始值不會報錯 * 1. 終級規則: java中的變量在使用時,必須有值!!! * 2. final修飾的成員變量沒有默認值 * 3. 現象歸納: * 1. final修飾變量 如果可以 直接賦值 * 2. final修飾成員變量 , 可以在構造方法中賦值 (如果有多個構造,必須都要賦值,也只會執行其中一個) * 3. final修飾局部變量, 只要保證使用前有值即可,不用不會報錯 */

6.static:修飾的成變不進堆

package com.itheima02.staticd; /* * static 修飾:1.屬性,2.方法,3.代碼塊 * static修飾屬性 * 1. 可以用類名/接口名 直接訪問 !!! * 問題: 為什么非靜態屬性必須對象調用? 而靜態屬性可以類名調用? * 因為static是屬于類的, 隨著類的加載而加載, 優先于對象 * 1. 非靜態屬性在堆里中,屬于對象的 (有幾個對象,就有幾份) * 2. 靜態屬性在方法區(類區)中, 屬于類的 (在內存只有一份,共享一值) * * 2. 靜態屬性 也可以 通過對象名來調用(不推薦) : 每個對象實際上都是類的實例 * 3. 靜態屬性 被該類所有對象所共享 (只有一個對象進行修改,那么其他對象的該靜態屬性都會隨之修改) * 運用: 非靜態屬性各自對象私有, 靜態屬性大家共有 */ public class StaticDemo01 {public static void main(String[] args) {/* A a = new A();System.out.println(a.i); // 可以,a為對象System.out.println(A.j);*/ //可以,A為類名A a1 = new A();a1.i = 2;A a2 = new A();System.out.println(a2.i);// 1,不是2System.out.println(A.j); //以下這幾個都一樣都為2System.out.println(a1.j);System.out.println(a2.j);System.out.println("--------------------");a1.j = 10;System.out.println(a2.j); //10,j靜態,改了都改a2.j = 20;System.out.println(a1.j); //20System.out.println(A.j); //20System.out.println("--------------------");Student s1 = new Student();Student s2 = new Student();s1.schoolName = "黑馬";System.out.println(s2.schoolName); //黑馬Student.schoolName = "白馬";System.out.println(s1.schoolName); //白馬} } class A{int i = 1; //非靜態屬性static int j = 2; //靜態屬性,不給值也沒事,因為static可以使用默認初始值,不是final } class Student{String name;int age;int money;static String schoolName; } package com.itheima02.staticd; /* * static修飾方法:0. static隨著類的加載而加載, static內容屬于類不會進堆。static修飾的內容加載時會進方法區(靜態區/類區),非static修飾的內容加載時會進方法區(非靜態區/對象區)。 * * 1. static方法 可以通過類名調用 * 問題: 為什么 非靜態方法地址 要記錄到 堆內存? * 原因: 非靜態方法 可以訪問 非靜態屬性 , 不同的對象的非靜態屬性是不一樣的 * 不同的對象 非靜態方法 執行效果也有所不同,所以涉及對象,進堆 * * 2. static屬于類的,跟對象無關 (static優先于對象加載 : 先來調用后到的) * 2.1 static方法不能調用非靜態的屬性和方法(跟對象有關系都不可以) * 2.2 this 和super關鍵字都不行 * 只要該類對象, 調用靜態方法執行效果都一樣!!! */ public class StaticDemo02 {public static void main(String[] args) { B b1 = new B(); b1.name = "張三";B b2 = new B(); //又new了,地址不同b2.name = "李四";b1.method01(); //張三:method01 com.itheima.demo02.B@4554617cb2.method01(); //李四:method01 com.itheima.demo02.B@74a14482b1.method02(); //static method02b2.method02(); //static method02B.method02(); //static method02B b = null; //null指堆是空的,找不到method01()//b.method01(); //NullPointerException 空指針異常 空引用b.method02(); //static method02,對象是空的也沒事,靜態方法不進堆} } class B{String name;public void method01(){System.out.println(name + ":method01");System.out.println(this); //com.itheima.demo02.B@4554617c//System.out.println(this.name); }public static void method02(){//public和static位置無所謂,只要在返回值前就可以System.out.println( "static method02");} }

如下method02靜態,this屬于對象,所以報錯。加上name+"static…"會報錯,因為name非靜態,定義改為static String name就可以。

package com.itheima02.staticd; /* * static 修飾屬性和方法 * 1. static 屬性 * 1. 訪問 : 類名.靜態屬性 (標準) * 對象名.靜態屬性(可以,不推薦) * 2. 靜態屬性在內存獨一份,該類所有對象共享,其中一個對象,其他對象該屬性都會改變 * 3. 運用: 類的公共屬性設置靜態(比如: 一個學校的學生: schoolName) * * 2. static 方法 * 1. 訪問 : 類名.靜態方法 (標準)* 對象名.靜態方法(可以,不推薦)* 2. 靜態方法 不可以調用 非靜態的內容 (類先加載,再創建對象)* 靜態屬于類的,隨著類的加載而加載的。補充: 非靜態可以調用靜態* 非靜態內容: 屬性,方法, this,super...* 3. 運用: 只要這個方法跟對象中其他內容無關,都可設計static* 好處: 節省內存,調用方便*/ public class StaticDemo03 { //這類名和main方法無關,只是借用類名調用下main方法,所以main是靜態的 // static int i;public static void main(String[] args) { //右擊運行時jvm會調用main這個入口方法int add = C.add(1, 2); //這行不創建對象,好處節省內存,不用在堆上創建空間System.out.println(add); //3// System.out.println(i); //上面第一行static int i注釋放開可以 //0method03();C c = new C();c.method01(); // 1 2 2 //非靜態對象名.調用}private static void method03() { // 默認static,因為main是static} } class C{int field = 1;static int sField = 2; public void method01(){System.out.println(field);System.out.println(sField);method02();}public static void method02(){ // System.out.println(field); //非靜態報錯 // method01(); //非靜態報錯System.out.println(sField);}public static int add(int a, int b){ //這個方法獨立于這個對象之外,設計為靜態return a + b;} } package com.itheima02.staticd; /* * 需求場景: 安裝軟件/驅動 只要做一次 * 靜態代碼塊 * static{ * // 代碼 * } * 1. 隨著類的加載而執行, 優先于構造, 只執行一次 * 2. 只要類加載就能運行,無需手動調用 * 3. 運用: 數據庫 (注冊驅動) */ public class StaticDemo04 {/** 右單擊: javac xx.java -> java xx(ideal幫做)* 運行: JVM底層 StaticDemo04.main(args) 【main是靜態方法,類名.調用】* 1. 類先加載 : static代碼塊先運行,比main方法更快* 2. 輪到static方法*/static{System.out.println("xx");}public static void main(String[] args) {D d1 = new D();D d2 = new D();D d3 = new D();System.out.println("yy");} } class D{static{System.out.println("隨著類的加載而執行,無需手動調用");System.out.println("因為類的加載全局只有一次,所以static代碼塊全局只執行一次");System.out.println("類的加載優先于對象創建,static代碼塊最先執行的");}public D(){System.out.println("D的構造方法");}//方法需要手動調用static void method(){System.out.println("靜態方法");} }


如下沒有創建對象,沒有調用方法,運行依然顯示:靜態代碼塊。

如下因為info是static,所以assign方法也應為static。

如下不確定=非靜態。

7.四大權限修飾符:記住中間兩個本包,ppdp

package com.itheima03.privilege; import com.itheima00.question.Fu; /* * java四大權限修飾符:public > protected > default(不寫) > private * 1. public : 公共的 , 全工程可訪問 * 2. protected : 受保護的 , 【本包 + 跨包子類內部】 * 3. default : 默認, 【本包】 * 4. private: 私有, 除【本類】內部,其他不可訪問 */ public class FourDemo {public static void main(String[] args) {Fu fu = new Fu();Zi zi = new Zi();} } class Zi extends Fu{ public void eat(){System.out.println(id1);System.out.println(id2); //跨包 子類的內部可訪問 //import com.itheima00.question.Fu;} } package com.itheima04.review; /* * 修飾符:static,final,abstract,default * 修飾符矛盾 (編譯報錯): * 1. private 和 abstract 不能共存: abstract方法不重寫沒有意義,但是private方法又不能被重寫 -> 矛盾 * 2. final 和 abstract 不能共存: final修飾的方法不能被重寫 * 3. static 和 abstract 不能共存: static方法也不能被重寫,因為static方法屬于類 */ public class XiuShiFuDemo {public static void main(String[] args) {} } abstract class A{abstract void method01(); //沒有{}方法體,前面沒有public,只有接口默認有publicprivate static void method02(){ //可以,只能在本類里讓其他方法調用如下}static void method03(){ method02();} } package com.itheima04.review; //這部分代碼面板效果如下圖 public class Demo02 {public static void main(String[] args) {} } interface MyInterface{int I = 1; //public static final //final修飾可以用構造賦值,但interface沒構造,寫完就賦初始值void method(); // public abstract } abstract class MyClass{public int id1;protected int id2;int id3;private int id4; public MyClass(){}public static int id5;public final int id6 = 1;public static final int id7 = 1;public String method(int a, int b){return "";}public abstract void method2(); } class F extends MyClass{@Overridepublic void method2() {} }

抽象方法:半粉色。f:黃色屬性

8.native:調用C/C++

package com.atguigu.test02; /** native:也是一個修飾符* 1、意思:原生的、本地的* 2、可以修飾什么?可以修飾方法* 3、它修飾的方法有什么不同?* 語法格式:* 【修飾符】 class 類{* 【其他修飾符】 native 返回值類型 方法名(【形參列表】);* }* native修飾的方法,看不見方法體。* native修飾的方法,不是用Java語言實現的,而是調用了底層C/C++的代碼,這些代碼* 被編譯為.dll文件(windows下.dll,linux下是.lib文件),讓Java來執行。 * * (1)native方法,對于Java程序員來說,該怎么調用還怎么調用* (2)子類還可以選擇對它進行重寫*/ public class TestNative {public static void main(String[] args) {Object obj = new Object();System.out.println(obj.hashCode());// 151.....MyClass ob = new MyClass(); //不能為obj和上面同名System.out.println(ob.hashCode());// 1} } class MyClass extends Object{//重寫父類的native方法@Overridepublic int hashCode() {return 1;} }

D:\development\jdk1.8\jre\bin 文件夾里有很多.dll文件。

總結

以上是生活随笔為你收集整理的【Java4】实例初始化,类初始化,/接口,多态,final/static,权限修饰符/native的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。