面試題:請說說抽象類和接口的區別
抽象類,使用abstract關鍵字修飾的類為抽象類,一般來說,含有抽象方法的類就需要定義為抽象類,但是抽象類不一定都有抽象方法,比如,在GUI當中,對于事件處理提供了很多監聽器口里里面方法都是抽象的,每次進行事件處理時,都需要實現監聽器接口,哪怕只處理一個簡單的動作,也需要實現接口所有的方法,這樣很麻煩,而且顯得代碼很臃腫,Java提供了適配器,適配器就是自己實現了監聽器接口,但是所有的方法都是空實現,以后再用到監聽器時,我們可以繼承適配器,實現我們需要的方法就可以了,這樣就很方便。像這樣的適配器只是給調用者提供一個方便,一定不希望別人直接創建實例來使用,所以有必要將它定義為abstract抽象的。
接口,接口是一種特殊的抽象類,接口中所有的方法都是抽象的,通常來講,我們使用接口作為一種協議,起到各模塊之間的銜接作用。由于Java中只支持單繼承,不支持多繼承,但是可以實現多個接口,原因在于接口中所有的方法都抽象,子類繼承哪個都無所謂,我們讓一個類實現多個接口,就可以做到將一個子類對象當做多種父類類型來使用,所以我認為定義接口就是為了更好地實現多態,因為多態就是把子類當做父類來用.
1 /* 2 子類對象的實例化過程 3 我們可以用一個類的變量記住它的子類的子類的實例.這時如果調用子類中的方法,只需要強制轉換子類就可以 4 沒必要非得強制轉換子類的子類. 5 instanceof關鍵字:也可以判斷子類實例也屬于父類的類型. 6 */ 7 8 class A 9 { 10 A() 11 { 12 //如果程序沒有寫構造方法的/java會默認給它添加構造方法! 13 } 14 public void a() 15 { 16 System.out.println("a() in A"); 17 } 18 } 19 20 class B extends A 21 { 22 B() 23 { 24 super(); //默認調用父類的無參的構造方法! 25 } 26 public void a() 27 { 28 System.out.println("a()in B"); 29 } 30 31 public void b() 32 { 33 System.out.println("b()in B"); 34 } 35 36 } 37 38 class C extends B 39 { 40 public void a() 41 { 42 System.out.println("a()in C"); 43 } 44 public void b() 45 { 46 System.out.println("b()in C"); 47 } 48 public void c() 49 { 50 System.out.println("C()int C"); 51 } 52 } 53 class Demo 54 { 55 public static void main(String[] args) 56 { 57 A a = new C(); 58 if(a instanceof C) 59 { 60 C c =(C)a; 61 c.c(); 62 } 63 if(a instanceof B) 64 { 65 B b = (B)a; 66 b.b(); 67 } 68 } 69 }
/* 繼承的細節 1.子類不會繼承與父類的私有的成員 2.構造函數是不會被繼承. 3.只支持單繼承,可以多重繼承. ------------------ 1.以后在設計一個類的時候,父類一定要加上一個不帶參數的super,否則子類實例化的時候會報錯! 為什么有這樣一個機制: 解答:別人來繼承與這樣一個類,一定也需要這個子類具有父類的方法.但是別人并不知道在構造函數里面做了一些特別才能實現這個 的功能.所以java就規定子類實例化的過程中.一定會默認調用與父類的super()的構造方法.如果你在父類中沒有定義一個無參的. 那么在實例化的過程中是會容易出錯的. */ class Person { private String name ; public Person(String name) { this.name = name; } public Person() { //咱們加一個無參的構造方法! } public void eat() { System.out.println("是人都要吃東西!"); } } class Student extends Person { public Student() { //不帶參數的構造函數! super(); //默認為這個? 但是有這個父類的構造函數嗎?顯然沒有對吧.。 } public void eat() { System.out.println("抽一根"); super.eat(); } } class Demo { public static void main(String[] args) { Student st = new Student(); st.eat(); } }
/* 子類的實例化過程:子類在創建做了什么事情呢? 解答:在創建子類的時候,會調用子類的構造函數,在子類構造函數的第一行會默認調用父類的構造函數 在子類構造函數中如果沒有顯式地調用父類的構造函數.它會自動的調用父類的無參的構造函數(在這個問題上你要注意) 我們可以在構造函數中使用this(實參)來調用自己的帶參數的構造方法 還可以用super(實參)去調用父類型的帶了參數的構造方法/ 但要注意:this 與super()只能出現一次. 并且在第一行. 如果一個構造函數調用了this ,那么就不能從第二個語句使用super() */ class Person { private String name ; public Person() { System.out.println("無參的Person()被調用啦!"); } public Person(String name ) { this(); System.out.println("有參的Person()被調用啦!"); this.name = name; } } class Student extends Person { private String name; public Student() { super("kudy"); System.out.println("無參的Student()被調用啦~"); } public Student(String name) { this(); //與super()不能同時出現 System.out.println("有參的Student()被調用啦~"); } } class Demo { public static void main(String[] args) { new Student("abc"); } } /* 輸出的結構為: -------------------------------- 無參的Person()被調用啦! 有參的Person()被調用啦! 無參的Student()被調用啦~ 有參的Student()被調用啦~ */
/* 關于多態: 不變應萬變 */ abstract class Person { public abstract void eat(); } class Chinese extends Person { public void eat() { System.out.println("中國的人還是廣東人最好啦!"); } } class Shop { public void shopping(Person p ) { System.out.println("咱們去買好東西吃!"); p.eat(); } } class Demo { public static void main(String[] args) { Shop shop = new Shop(); shop.shopping(new Chinese()); } }
/* 子類實例化的面試題! A1 B2 B1 */ class A { String name = "張三"; public A() { System.out.println("A1"); //A1 } public A(String name) { this(); System.out.println("A2"); } } class B extends A { String name = "王五"; public B() { this("張"); //如果有了this 就是默認沒了super() System.out.println("B1"); } public B(String name) { // super(); System.out.println("B2"); //B2 } } class Demo { public static void main(String[] args) { new B(); } }
/* 覆蓋父類的方法: 子類當中覆蓋父類的方法必須要和父類具有相同的方法名,具有相同的參數類型,具有相同的返回值 返回值類型一定要和 子類的保持一直.這樣就是方法的重寫 子類的方法的權限不能比父類有更嚴格的訪問權限,因為我們經常要把子類當做父類來使用. 子類去訪問父類的方法時,會比較一下子類的訪問權限.如果權限比父類小.那么就掛啦 多態: 把子類當做父類來使用,針對父類進行方法的調用.傳入不同的子類.執行的結構是一樣的. 除非父類被子類這個哥們重寫啦方法~ */ class Person { public void run() { System.out.println("run() in Person"); } public Person getInstance() { return new Person(); } } class Student extends Person { public void run() { System.out.println("happy"); super.run(); //調用了父類的run方法! } public Student getInstance() //權限不應該比父類的要小. 如果權限要比父類的小.那么就OH.Sorry { return new Student(); } } class Demo { public static void main(String[] args) { Student stu = new Student(); stu.run(); run(stu); } //實現了多態! public static void run(Person p ) { p = p.getInstance(); p.run(); //實現了多態 } }
/* final 關鍵字:最終的!終態的 1.被fina修飾的屬性為常量,是不能被更改的.也就是說:值是不能被改變 2.final所修飾的方法不能被重寫,也就是說不能被子類所覆蓋 3.final修飾所修飾的類是不能被繼承的! 一般fina的用法:public static fina String NAME = "kudy"; 為什么它一般是和static一起的呢? 解答: 既然一個屬性都不能被修改啦.是一個常量啦.咱們可以把他定義一個static的.在類出生的時候.它也會跟著出生. 方便. */ /* final class Person { //被final所修飾的類是不能被繼承的! } */ class Person { public static final int NUM = 19 ;//給我修飾的常量是不能被修改的! public final void show() { System.out.println("給我修飾的方法都是不能被重寫!"); } } class Student extends Person { /* public void show() { System.out.println("真的是不能被重寫噢!"); } */ public void run (int num) { //先比較后自加! System.out.println(++num); System.out.println(num++); //? 為多少呢? 20 //因為第一次自加1 后來第二次的時候。先輸出值它自己再加1 } } class Demo { public static void main(String[] args) { Student stu = new Student(); stu.run(stu.NUM); } }
/* 設計模式!組合 組合:當一個對象在運作的過程中必須要用到另外一個對象的時候,然而又不是構成繼承的關系的! */ class Guo { public void heat() { System.out.println("已經自動的加熱啦~"); } } class Chef { //吃食品的時候一定要把它加熱嘛~~ Guo guo; Chef(Guo guo) { this.guo = guo; } public void cook() { guo.heat(); } } class Demo { public static void main(String[] args) { Chef chef = new Chef(new Guo()); chef.cook(); } }
/* 這樣也是一個簡單的組合! */ class Card { public void spend() { System.out.println("一不小心就花了600RMB"); } } class Person { Card card ; public Person(Card card) { this.card = card; } } class Chinese extends Person { public Chinese(Card card) { super(card); } } class Shop { public void Shopping(Person p ) { System.out.println("happy完畢!"); p.card.spend(); } } class Demo { public static void main(String[] args) { Shop shop = new Shop(); shop.Shopping(new Chinese(new Card())); } }
/* 抽象類: 1.沒有方法體必須要聲明為abstract抽象方法 2.含有抽象方法的類一定是抽象類 3.抽象類的定義:用abstract修飾的類叫做抽象類 4.抽象類是不能被實例化的(也就是說不能創建對象!); 5.可以用一個抽象類來繼承一個抽象類.會繼承所有的方法 6.如果用一個類來繼承抽象類,那么必須要實現抽象類里面所有的方法 7.抽象類的訪問權限沒有什么特殊之處.主要是看修飾符! 8.抽象類里面不一定有抽象方法.但是包含有抽象方法一定是抽象類 */ abstract class A { abstract void a();//抽象方法! public void run() { System.out.println("A run()"); } } abstract class B extends A { abstract void b(); } class C extends B { //必須要把它所繼承的所有的抽象方法實現! public void a() { System.out.println("A.class"); } public void b() { System.out.println("B.class"); //實現B } } class Demo { public static void main(String[] args) { A a = new C(); if(a instanceof C) { C c = (C)a; c.a(); c.b(); c.run(); } } }
/* 如果有多個類具有相同的方法聲明,但是方法的實現細節不一樣. 我們就需要定義抽象類. 抽象父類 里面可用到的新學習的知識 : 組合哦 */ abstract class Person { public abstract void eat(); public void run() { System.out.println("吃完飯跑步是最好的!"); } } class Man extends Person { public void eat() { System.out.println("大口大口的吃!"); } } class WoMan extends Person { public void eat() { System.out.println("小口小口的吃!"); } } class Begin { private Person p; public Begin(Person p) { this.p = p; } public void getBegin() { p.eat(); p.run(); } } class Demo { public static void main(String[] args) { Begin begin = new Begin(new Man()); begin.getBegin(); } }
//甲寫的代碼 class C { public void run(A a) { a.c(); } } abstract class A { abstract void a(); abstract void b(); abstract void c(); //我這里有一個C是被子類所重寫啦! abstract void d(); abstract void e(); abstract void f(); } abstract class AbstractB extends A //需要我都可以實現!但是我用到這種方式! { public void a() { } public void b() { } public void c() //哥們.你也有啊!是不是OH啦 { } public void d() { } public void e() { } public void f() { } } class B extends A { public void a() { } public void b() { } public void c() //哥們.你也有啊!是不是OH啦 { System.out.println("c() in B"); } public void d() { } public void e() { } public void f() { } } class Demo { public static void main(String[] args) { /* C c = new C(); c.run(new B()); */ C c = new C(); //為什么抽象的都可以new呢?但要注意.我這個是匿名內部類 c.run(new AbstractB(){ public void c() { System.out.println(" AbstractB in C"); } } ); } }
/* 模板方法的設計模式: 定義一個抽象類作為模板,將具體做事情方法定義出來,但是不實現 2.對外提供一個共有的方法作為接口,規定做事情的順序/這個方法應該為final 避免了讓子類重寫 子類繼承模板,實現所有的抽象方法() */ abstract class AbatractPrint { abstract void opend(); abstract void print(); abstract void close(); //定義成終態的.避免了子類所修改! public final void run() { this.opend(); print(); close(); //調用方法! } } class StringPrint extends AbatractPrint { private String data; StringPrint(String data) { this.data = data; } public void opend() { System.out.print("<<"); } public void print() { System.out.print(data); } public void close() { System.out.print(">>"); } } class Demo { public static void main(String[] args) { AbatractPrint abatractPrint = new StringPrint("kudy"); abatractPrint.run(); //使用匿名內部類做一下這道題目! //我現在不是為了抽象類創建對象.而是為了匿名子類! //也多多態的一種形式! //匿名內部類重寫了父類的方法!并且調用一把run(); new AbatractPrint(){ public void opend() { System.out.print("<<"); } public void print() { System.out.print("show"); } public void close() { System.out.print(">>"); } }.run(); } }
//定義抽象類作為接口,實現個模塊之間的解耦 /* 首先第一種方法的: 顯示就是三個人不能同時分工協作啦~~ 咱們傳入的時候要注意: 我們傳入的是子類. 父類型的引用指向了子類型的對象。 */ //定義一個抽象的數據產生器! import java.io.*; abstract class Generator { abstract String getData(); } //定義一個抽象的數據處理器 abstract class DataHandler { abstract String handleData(Generator generator); } //甲負責寫數據產生器 class OneGenerator extends Generator { public String getData() { return "hello"; //產生了一個數據! } } //乙所負責寫的數據處理代碼 class OneDataHandler extends DataHandler { public String handleData(Generator generator) { String data = generator.getData(); return "~~"+data+"~~"; } } //數據產生器! class TwoGenerator extends Generator { public String getData() { return "小細加油"; } } //數據處理器! class TwoDataHandler extends DataHandler { public String handleData(Generator generator) { String data = generator.getData(); return "~~~"+data+"~~~"; } } /* 數據顯示! */ class Demo { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); /* DataHandler data = new OneDataHandler(); Generator gen = new OneGenerator(); */ //通過讀取鍵盤獲得用戶使用的數據產生器名字 System.out.println("請輸入您使用的數據產生器:"); String generatorClassName = br.readLine(); //根據類名反射出類 //Class class -->new Class()對象 --》class.Class //1-1根據類名反射出類! Class generatorClazz = Class.forName(generatorClassName); //類 //又因為返回的是object 類型/所以我們要強制轉換.否則沒有辦法賦值。 //根據類創建實例對象(數據產生器) Generator generator=( Generator) generatorClazz.newInstance(); //類創建對象。并且是父類型的引用指向子類型的對象。 //2.通過反射獲得數據的處理器對象 System.out.println("請輸入您要使用的數據處理器:"); String dataHandlerClassName = br.readLine(); Class dataHandlerClazz = Class.forName(dataHandlerClassName); DataHandler dataHandler = (DataHandler)dataHandlerClazz.newInstance(); String data = dataHandler.handleData(generator); System.out.println(data); } }
/* 內部類: 1.在類中定義的類我們稱之為內部類,它是外部類的一個成員。 2.內部類可以直接訪問外部類的成員,但是外部類不能直接的去調用外部類的成員、 其實內部類調用外部類的成員的時候.其實是使用到了:類名.this.變量名 來訪問外部類的成員。 3.在內部類中的方法可以使用this引用調用這個方法的內部類對象. */ class Outer { String name = "張三"; public void run() { System.out.println("Outer is Running"); } public void show() { System.out.println("My name is Outer"); System.out.println(new Inner().age); } class Inner { int age = 19; public void run() { System.out.println("Inner is Running"); } public void eat() { this.run(); //this.代表方法所調用的對象.它的對象是inner 所以輸出的是inner show(); //因為創建內部類的時候.外部類的對象已經創建了. 如果虛擬機在內部類中找不到.它會到外部類去找這個show()對象. System.out.println(Outer.this.name); //其實同等于:Outer.this.name //類名.name System.out.println("Nnner is Eat"); } } } class Demo { public static void main(String[] args) { Outer.Inner inner = new Outer().new Inner(); //類型要一致! inner.run(); inner.eat(); } } /* 可以在方法中定義內部類? System.out.println(age);為什么會訪問不了呢.編譯出錯/ 其實:當我們在外部類調用A對象的時候.run()方法由于age是存儲在棧內存的臨時變量中的. 當我們對象調用完畢過后呢. 有可能是會被釋放調的.而當你再次調用的時候 age 的時候呢.由于虛擬機可能會被釋放.所以調用不了. 那么:虛擬機認為你這樣做是編譯錯誤的! */ class A { String name = "小細" ; public void run() { int age = 19; class B { public void run() { String name = "王五"; System.out.println("my name is B"); //System.out.println(age); System.out.println(A.this.name); //通過類名.this.屬性名訪問外部類的屬性. } } new B().run(); } } class Demo { public static void main(String[] args) { A a = new A(); a.run(); } } /* 匿名內部類: */ class Fruit { public void qupi() { } } class Person { public void eat(Fruit f) { f.qupi(); System.out.println("吃完啦!!"); } } class Demo { public static void main(String[] args) { Person p = new Person(); p.eat(new Fruit(){ public void qupi() { System.out.println("Apple把皮弄開!"); } } ); } } /* static修飾的靜態內部類: 1.靜態的內部類可以聲明非靜態的屬性和方法. 但是靜態的內部類是不能訪問外部類非靜態的方法.因為外部類的屬性需要創建對象才能調用. 你內部類是不需要創建對象的.所以調用不了。 2.靜態的內部類不能訪問非靜態的屬性. */ class Outer { static String name = "kudy"; String ID = "888"; static class Inner { int age = 19; public void run() { System.out.println(age); System.out.println("Inner is happy"); System.out.println(Outer.name); //因為是不需要創建對象的.所以可以使用Outer.name訪問外部的靜態的方法。 // System.out.println(Outer.ID); } } } class Demo { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); //靜態的內部類一定要靜態的去創建! //System.out.println(inner.age); inner.run(); } } /* 類的繼承 1.使用extends關鍵字來聲明類的關系 2.子類會自動繼承父類的屬性與方法 */ class Person { String name ; public void run() { System.out.println("Person is Running"); } } class Man extends Person { public void toLike() { System.out.println(name +"運動"); //默認會添加上this的 } } class Demo { public static void main(String[] args) { Man man = new Man(); man.name = "小細"; man.run(); man.toLike(); } } /* 類的繼承是為了實現代碼的復用性,如果有多個類具有相同的方法.我們應該盡量把她抽出一個類來 */ class Person { String name ; int age; public void eat() { System.out.println(name+"吃飯"+",年齡為:"+age); //this.name this.age } public void run() { System.out.println("需要運動"); } } class Student extends Person { public void eat() { System.out.println("吃一口飯"); super.eat(); //調用父類的方法、。 System.out.println("看一下作業"); } } class Teacher extends Person { public void eat() { System.out.println("抽一根"); super.eat(); System.out.println("再來一根"); } } class Demo { public static void main(String[] args) { Student student = new Student(); student.name = "小細"; student.age = 19; student.eat(); student.run(); } } /* 父類型的引用指向子類型的對象.也就是想上類型轉換.不需要強制轉換 強制轉換的要求: 父類型的引用指向子類型的對象。 3.把父類當做子類來使用是不行的,因為子類有的.父類型不一定有 4.當做子類當做父類來用時,只能使用父類型所擁有的方法。 如果調用子類擁有的方法.編譯器會報錯!所以需要強制轉換.但在強制轉換的前提下我們要知道父類型的引用是否是指向了子類型的對象 強制轉換之前需要判斷一下. 注意: 1.當你父類型的引用指向子類型的對象的時候.你必須要清楚的就是:你訪問的屬性是會是父類的.而不是子類的. 因為java在屬性方法是做了靜態的綁定.誰是我的類型.我就去誰的類型去找.而方法就剛好相反. 方法就是:誰指向誰.我就調用誰的方法.。 因為是做了動態的綁定。 */ class Typist { String name = "小細"; public void type() { System.out.println("typeing"); } } class Coder extends Typist { String name = "王五"; public void type() { System.out.println("tepeing slowly!!!"); } public void code() { System.out.println("Codeing"); } } class Demo { public static void main(String[] args) { //向上類型轉換: 父類型的引用指向子類型的對象. Typist typist = new Coder(); //typist.type(); 因為你是指向了子類型的引用.所以java做了動態綁定.也就是說你綁定了一個子類型的方法。 System.out.println(typist.name); /* 為什么輸出小細呢.因為java在檢查的時候.屬性是不做動態綁定的.也就是說.類型是誰.他就會找類型里面的屬性. */ /* Code code = new Typist(); 子類型的引用不能指向父類的對象.因為子類有的.父類型不一定有. */ Coder coder; if(typist instanceof Coder) //父類型的引用指向子類型的對象才可以搶走轉換! { coder = (Coder)typist; //強制轉換成子類 System.out.println(coder.name); } } } /* 因為java的屬性在父類型的引用指向子類型的情況是做了靜態的綁定的.所以我們可以這么做! */ class Person { private String name = "無名氏"; public String getName() { return name; } public void eat() { System.out.println("eating"); } } class A extends Person { private String name = "小細"; public String getName() { return name; } } class B extends Person { String name = "kudy"; } class Demo { public static void main(String[] args) { Person p = new A(); /* 因為java的父類型的引用指向子類型的對象的時候.方法使用了動態.而屬性只使用了靜態.也就是說:類型是那個.屬性就是從 那里去找 */ System.out.println(p.getName());//這樣就是調用了子類型的屬性啦~~ } } /* 什么情況下使用子類當做父類來使用 匿名內部類:new一個父類對象,后面跟一個花括號,這時不需要創建父類的實例 */ class Person { String name = "無名氏"; public void eat() { //每個人的愛好不同! } } class Restaurant { public void run(Person p) { p.eat(); } } class Chinese extends Person { public void eat() { String name = "中國人"; //在方法里面是動態調用的哦。 System.out.println(name+"我是拿筷子吃的!"); } } class American extends Person { public void eat() { String name = "美國人"; System.out.println(name+"我只吃漢堡包!"); } } class Demo { public static void main(String[] args) { Restaurant r = new Restaurant(); //r.run(new American()); r.run(new Chinese()); /* 內部類: class JB extends Person { public void eat() { System.out.println("我是吃垃圾的!"); } } r.run(new JB()); */ r.run(getIndia()); } static Person getIndia() { String name = "印度菜"; Person p = new Person(){ //我創建了一個子類.子類里面有eat方法重寫啦.之后呢.再把這個重寫好的對象返回來.也就是說:父類型的引用指向子類型的對象 public void eat() { System.out.println(this.name+"印度菜"); } }; return p; } } class A { String name = "小三"; public String getName() { return name; } public void run() { System.out.println(name); } } class B extends A { private String name = "小四"; public String getName() { return name; } public void run() { System.out.println(name); } public void show() { System.out.println("我是子類!"); } } class Demo { public static void main(String[] args) { A a = new B(); //父類型的引用指向子類型的對象. 就可以使用子類型與父類型所共同擁有的方法.但是子類出來的就不行。 // a.show(); /* System.out.println(a.name); 如果這樣寫出來是小三,而不是小四,但是在方法里面輸出來的就是小四.因為她的屬性在方法里面運行啦.所以是動態的. 而你單獨如果想輸出它的屬性的話,它是根據了靜態綁定來進行操作.也就是輸出了類型里面屬性的內容! 那方法就是: 給所有的變量私有化.給他開一個public方法.返回屬性!!因為方法是可以轉換為動態的. 有的人可能會問?不相同可以嗎? 如果不相同的話.前面已經說過: 就是子類型所特有的.你父類型是不可以調用.除非需要強制轉換! */ String name = a.getName(); //這時候方法已經給重寫 System.out.println(name); //輸出的會是小四 } } /* 對象的比較: 對象的比較不能使用 == 這樣比較的是比較地址. 應該用equals方法 因為所有的類都是默認的繼承與Object! 我們可以重寫它里面的equals比較方法。 */ class Person { private String name ; private int age ; public Person(String name ,int age) { this.name = name ; this.age = age ; } @Override //告訴編譯器我重寫父類型的方法! 大寫的O //重寫父類的方法! public boolean equals(Object obj) { if(this == obj) return true; if(obj instanceof Person) //如果你父類型的引用是指向了子類型的對象的.那么就判斷. { //因為是按照了父類型的引用是指向了子類型的對象.首先我們要判斷一下.強制類型轉換.要不然我們是調用不了子類型的內容 Person p =(Person)obj; if(this.name.equals(p.name)&&this.age == age) return true; } return false; } } class Demo { public static void main(String[] args) { Person p1 = new Person("張三",19); //p1就是當前對象! Person p2 = new Person("張三",19); System.out.println(p1.equals(p2)); } } class Person { String name ; public void eat() { } } class Restaurant { public void show(Person p) { p.eat(); } } class Chinese extends Person { String name = "中國人"; public void eat() { System.out.println(name+"我吃中國菜!"); } } class Test { public static void main(String[] args) { Restaurant r = new Restaurant(); r.show(new Chinese()); /* 匿名內部類的第一種用法! */ r.show(new Person(){ public void eat() { System.out.println("日本人吃日本菜!"); } } ); r.show(getUSA()); } public static Person getUSA() { Person p = new Person(){ public void eat() { String name = "美國人"; System.out.println(name+"吃美國菜!"); } }; return p; } }
使用Java的文檔注釋
文檔注釋以“/**”開始,以“*/”標志結束,相應的信息和批注所對應的位置很重要! 類的說明應在類定義之前,方法的說明應在方法的定義之前。
批注參數來標記一些特殊的屬性及其相應的說明 。
@author<作者姓名>
@version<版本信息>
@param<參數名稱><參數說明>
@return<返回值說明>
生成文檔的命令
javadoc -d Engineer -version -author Engineer.java
心得:
我要向前沖,想前沖。
一.構造函數的定義與作用
1.函數的名次與類同名
2.沒有返回值類型
3.不能使用retrun 關鍵字來返回一個值
注意》》:沒有返回值類型聲明不等同于“void”,void也是一種返回值的聲明(如果寫上了void,那就是一個普通的方法啦!)
二.構造函數的具體應用
構造函數可以被重載
1.構造函數也一般的函數一樣,都是可以被重載的.但是參數類型要不一致.而且構造函數是沒有返回值
構造函數如果被調用?
2.使用new關鍵字來創建對象的時候,會自動的調用一個類的構造函數.也可以在一個類中利用this();來調用其他的構造函數!
但是要注意:遞歸構造器調用. 普通函數的調用是:this.run(); 而構造函數調用是this();這樣來調用.
類必須要定義構造函數
3.其實每一個類中至少都有一個構造函數的,如果定義類時,沒有顯示的聲明任何的構造函數.系統會自動的為這個類創建了一個不帶任何參數的構造函數.
如果你在一個類中創建了一個顯式的構造函數.那么,虛擬機就不會自動的為你創建
構造函數的訪問權限
4.一般在定義構造函數的時,如果沒有特殊的需求(就好單例)應該使用public關鍵字來修飾構造函數
在一些特殊的情況使用private關鍵字
new Person()虛擬機做了什么事?
1.首先把類加載進來
2.為這個類創建對象.并且為成員變量初始化
3.自動的調用構造函數里面的內容
三:this關鍵字
this的引用
1.this關鍵字一般用于方法內
2.this代表是一個對象的引用
具體引用那個對象,就看這個調用方法的對象
this的應用場景
1.當在一個類中要明確指出使用對象自己的的變量或函數時就應該加上this引用 ,此時this是指當前對象自己。
2.當你要把自己作為參數傳遞給別的對象時,也可以用this關鍵字,此時this被作為參數傳遞。
在內部類中也會經常使用this關鍵字,此時this代表內部類對象,如想引用外部類對象,this前面還需要加上外部類的類名。
在構造函數中,可以使用this(實參)來調用該類的其他構造函數,此時,應注意,調用代碼只能在第一行,在別的方法中不能這樣調構造函數,在一個構造函數中只能調一個構造函數(因為都必須放在前面啦.所以只能調用一個)
四.函數的參數傳遞
1.基本數據類型在參數傳遞過程中值是不會改變的
(int ,byte,char,long,short,double,float,boolean )
2.引用數據類型在參數傳遞的過程中,其值是會被改變的.
五:static關鍵字之靜態變量
static關鍵字:在程序中使用static關鍵字來修飾一個成員
類什么時候加載?
類只會加載一次,又因為static修飾的變量是隨著類的加載而加載的. 所以其值是被任何的對象所共享.
1.靜態變量修飾的屬性是被所有類的實例所共享
2.靜態變量可以通過類名.屬性名直接訪問.(因為它是隨著類的加載而加載.只能加載一次)
3.靜態變量在類的加載時就完成了初始化.
第六:Static關鍵字之靜態方法
1.用static修飾的方法是靜態方法
2.在類加載后,就可以直接通過類名來調用靜態方法
3.可以使用類名.方法名來直接訪問
4.靜態方法的內部是不能直接的訪問非靜態的成員
原因:
因為靜態訪問在類加載后就可以直接調用了,而非靜態的成員則需要創建對象才可以調用.所以是不能直接的來訪問非靜態的成員
5.靜態方法內部,只能通過創建該類的對象才可以訪問非static的方法.靜態方法中是不能使用this關鍵字,因為靜態方法沒有別的引用. 靜態方法中也沒有所謂的對象。
6.靜態的方法的應用:
1. 一般在工具類上面.因為工具類是可以直接調用調用就可以使用了嘛.
2.生產對象中也可以使用。
面向對象:一種編程思想,使用對象來描述生活中的事物:
面向對象的四大特征: 1.封裝 2.繼承 3.多態 4.抽象
1.類和對象:
類是對象的抽象,對象是類的實例
2.this關鍵字是一個對象的引用,thiis在方法內,誰調用我.我就為誰服務
3.創建對象:
Person p ;
p = new Person();
1.在棧內存中定義一個變量p ,類型是:person
2.在堆內存中,首先加載一個Person.class字節碼
3.在堆內存中創建一個對象 new Person ()的一個實例
4.自動初始化堆內存里面的數據
5.把所創建的首地址變量賦值給p引用
4.對象的生命周期:
當對象被創建到失去所有的引用(沒有任何一個變量記住它的首地址,)這期間我們稱之為對象的生命
周期,當對象的生命周期結束后!就會變成垃圾對象,等待java的虛擬機回收!
5.匿名對象
1.匿名對象只使用一次就會被java的垃圾回收機制自動回收,用途:如果對一個對象只進行一次的調用,那么就可以使用匿名對象
2.咱們一般是在匿名對象作為實參傳送給一個函數。
2.類的封裝:
概念:將一系列特征相似的對象共同的屬性和行為抽象出來用一個類來描述.
類的成員變量描述的是屬性,類的成員方法描述的是對象的行為
為了實現良好的封裝性,需要將類的成員變量私有化(private),對外提供了set 與get方法
但是boolean 的最好使用 is
屬性私有化:
1.更加符合現實的邏輯
2.更加正確地控制別人的屬性訪問權限
3.防止一些錯誤的操作!
方法有時候也需要封裝.
3.構造函數:
1.函數的名稱一定要和類名相同
2.沒有返回值聲明
3.不能在語句中使用return 語句返回一個值!
構造函數的作用:
當我們使用new關鍵字來創建第一個對象的時,java的虛擬機就會自動的會調用構造函數.
我們可以為構造函數中做一些初始化的信息!
但要注意的問題:這個初始化的name 與age 并不是代表了:this的
構造方法的具體應用;
1.構造方法是可以被重載的(參數類型不一致就可以)
2.構造函數也可以添加訪問權限!不過一般建議使用public關鍵字來修飾.
個人心得總結:
今天的學習算是比較滿意吧!但是有一點注意的: 還是有一點點分心!
第二:認真聽課。
要多聽課!個人在感覺這塊了解不夠深入.
一、判斷題 1、Java語言是不區分大小寫的。 錯,Java語言是嚴格區分大小寫的 2、Java程序源文件的擴展名為“.jar”。 錯,Java程序源文件的擴展名為”.java” 3、Java程序一般應含有main方法,因為它是所有java程序的入口。正確 4、聲明main方法時,其聲明可以寫成: Public static void main(String args[]) 也可以寫成: Public static void main(String s[]) 不正確,P不應該大寫,應該小寫,其他地方是正確的 6、假設有一個名為Hello的java源程序,那么編譯這個文件的命令為javac Hello.java。 正確 7、當運行java程序時,類加載器將字節碼加載到內存中,字節碼檢驗器確認所有的字節碼是合法的并且不會破壞java的安全限制,然后解釋器讀取這些字節碼并將它們翻譯成計算機能夠執行的語言。 正確 8、在java語言中,每個ASCII碼英文字符占用8個二進制位,而每個中文漢字字符占用16個二進制位。FALSE 正確 英文字符占1個字節8位,中文字符占2個字節16位 9、short s = 64000語句是否正確。 不正確,超出short的取值范圍和應該在64000后面加上分號“;” 二、填空題 1、Sun公司提供了三種java開發工具:其用于工作站和個人計算機的標準開發工具為_ java se _____,用于企業級開發的工具為_java ee______,用于智能移動產品的工具為__ java me______。 2、Java程序中的數據類型分為哪兩種_基本數據類型和引用數據類型__________________________。 8種基本數據類型 數值型(byte short int long float double)字符型 char 布爾型 (Boolean) true 和false 引用數據類型 類,接口,數組 3、配置java開發和運行環境,通常需要配置哪兩個環境變量___path_______和________classpath____。 4、在java源文件中,可以有哪幾種類型的注釋_____單行注釋 多行注釋和文檔注釋___________________________。 5、查看當前java虛似機版本的java命令為___java -version________。 6、設一個java源文件的名字為Test.java,則編譯該文件的命令為_javac Test.java_____,運行的命令為___java Test___。 7、Java虛似機運行java程序過程為:首先從后綴為_.class____的文件加載代碼到內存中,然后在內存中__字節碼檢驗器檢查______代碼的合法性和安全性,然后___解釋器____執行合法和安全的代碼。 8、Java語言在____1995______年由____SUN______公司第一次正式發布的,__ 詹姆斯•戈斯林(James Gosling)________被譽為java之父。 9、設Hello.java文件的內容如下: class Hello { static void main(String args[]) { System.out.println(“Hello World!”); } } 下面說法正確的是:D A、 無法通過編譯,因為main方法聲明不對。 B、 可以編譯,但不可以運行。 C、 可以編譯,并可以輸出正常結果。 D、 可以編譯,但不可以運行,因為文件中沒有public類。 10、請寫出下面程序的運行結果____12_______: public class Test { public static void main(String args[]) { int i = 0; while(true) { if(i++>10) { break; } } System.out.printnln(i); } } X++和++X的區別: X++是X先參與運算再自增,++X是先自增再參與運算 11、請寫出下面程序的運行結果____11_______: public class Test { public static void main(String args[]) { int i = 0; while(true) { if(++i>10) { break; } } System.out.printnln(i); } } 12、請寫出下面程序的運行結果________4________ class Test { public static void main(String args[]) { int a=1,b=2; if((a==0)&(++b==6)) a = 100; System.out.println(a+b); } } (a==0)這個條件為false (++b==6)這個條件首先b自增1后再參與比較,b變成了3,但這個條件也不成立,所以”a=100;”這個語句沒有執行,最后(a+b)的值為(1+3)=4 13、請寫出下面程序的運行結果_____4______________。 class Test { public static int method(int x) { int j = 1; switch(x) { case 1: j++; case 2: j++; case 3: j++; case 4: j++; case 5: j++; default: j++; } return j; } public static void main(String args[]) { System.out.println(method(4)); } } 14、請寫出下面程序的運行結果_______7____________。 class Test { public static void main(String args[]) { int a = 2; switch(a) { case 1: a +=1; break; case 2: a +=2; case 3: a +=3; break; case 4: a +=4; break; default: a = 0; } System.out.println(a); } } 三、簡答題: 1、請判斷下面的程序是否能正常編譯并運行,如能編譯請寫出運行結果,如不能請改正。 int i = 0; do System.out.println(i++); while(i<5); 正確 :結果為 0 1 2 3 4 2、請指出下面程序可能出現的問題。 class Test { public static void main(String args[]) { int i = 0; do { System.out.println(i++); } } } 沒有while 語句,do語句沒有中止,不是正確的寫法 3、請總結break、continue和return的具體用法,并寫出相應的示例程序。 break于中止當前循環中的子語句 continue 語句只能出現在循環語句中,用于跳出循環的剩余語句塊,接著執行下一次循環 for(int i=0;i<10;i++) { if(i%2==0) { continue; } System.out.println(i); } return 用于結束當前執行的語句,并返回一個值 static int getMax(int num1,int num2,int num3) { int max=num1>num2?num1:num2; max=max>num3?max:num3; return max ; } 四、程序題: 1、 請編寫程序,計算1+3+5+……………………+1999的結果。 源程序://FindSum.java public class FindSum { public static void main(String args[]) { int n = 1999 ; int sum = findSum(n); System.out.println("從0到"+n+"之間的奇數和為:"); System.out.println("sum="+sum); } static int findSum(int n) { int sum=0; for(int i=0; i<=n; i++) { if(i%2==1) sum+=i; } return sum; } } 運行結果: 2、 請定義一個整數數組,用一種排序算法對這個數組進行排序。 源代碼://Demo42.java public class Demo42 { public static void main(String args[]) { int [] num = {12,45,10,23,5,123,89,411,9,78}; System.out.println("排序前:"); arrList(num); selectSort(num); System.out.println("排序后:"); arrList(num); } static void selectSort(int [] arr) { for(int i=0; i<arr.length-1; i++) { int pos = i; int max = arr[i]; for(int j=i+1; j<arr.length;j++) { if(arr[j]>max) { max = arr[j]; pos = j; } } exchange(arr,i,pos); } } static void exchange(int [] arr,int pos1,int pos2) { int temp; temp = arr[pos1]; arr[pos1] = arr[pos2]; arr[pos2] = temp; } static void arrList(int [] arr) { StringBuffer sb = new StringBuffer(); for(int i=0; i<arr.length; i++) sb.append(arr[i] + ","); sb.delete(sb.length()-1,sb.length()); System.out.println(sb); } } 運行結果: 3、 請用System.arraycopy實現數組的拷貝。 源代碼://Demo43.java public class Demo43 { public static void main(String args[]) { int [] num1 = {15,89,16,56,10,2,5,123,84,99,753,612}; int [] num2 = {789,145,100,20,36,95,88,71,40,126,91,65}; System.out.println("數組拷貝前:"); arrList(num1); arrList(num2); System.arraycopy(num1,3,num2,3,6); System.out.println("數組拷貝后:"); arrList(num1); arrList(num2); } static void arrList(int [] num) { StringBuffer sb = new StringBuffer(); for(int i=0; i<num.length; i++) { sb.append(num[i]+","); } sb.delete(sb.length()-1,sb.length()); System.out.println(sb); } } 運行結果: 4、 編寫一個程序,程序里定義三個數,并輸出這三個數的最大數。 源代碼://Demo44.java class Demo { public static void main(String args []) { int num1 = Integer.parseInt(args[0]); int num2 = Integer.parseInt(args[1]); int num3 = Integer.parseInt(args[2]); System.out.println("這三個數的最大值是:"); System.out.println(getMax(num1,num2,num3)); } static int getMax(int num1,int num2,int num3) { int max=num1>num2?num1:num2; max=max>num3?max:num3; return max ; } } 運行結果: 5、 編寫一個程序,這個程序把一個整數數組中的每個元素用逗號連接成一個字符串,例如,根據內容為[1][2][3]的數組形成內容為“1,2,3”的字符串。 源代碼://Demo45.java class arrDemo { public static void main(String args [] ) { int [] arr = {12,89,45,61,568,945,102,302,44,777,945,689}; System.out.println("依次輸出數組中的元素:"); arrList(arr); } static void arrList(int [] arr) { StringBuffer sb = new StringBuffer(); for(int i=0; i<arr.length; i++) sb.append(arr[i]+","); sb.delete(sb.length()-1,sb.length()); System.out.println(sb); } } 運行結果: 6、 編寫一個程序,從鍵盤上接受用戶輸入的需要轉的數,得到的一定是字符串,將此字符串轉換成十進制整數,然后打印出這個十進制整數對應的二進制形式。 源代碼://Demo46.java class appDemo { public static void main (String args []) { int num = Integer.parseInt(args[0]); System.out.println("輸入的整數為:"+num); System.out.println("這個十進制的整數對應的二進制形式為:"); ten2Binary(num); } static void ten2Binary(int num) { StringBuffer sb = new StringBuffer(); while(num>0) { int temp = num%2; num=num/2; sb.append(temp); } sb.reverse(); System.out.println(sb); } } 運行結果: 7、 請用移位的方式打印出一個十進制整數的十六進制形式。提示:按每4個二進制位對整數進行移位和去高位處理,得到的結果就是十六進制數的一位,然后按下面三種方式之一(作為作業,要求每種方式都用到)計算出一個十六進制數值對應的十六進制形式: 1)0-9之間的數值直接加上字符'0',9以上的數值減去10以后再加上字符'A' 2)定義一個數組,其中包含0-F這些字符,然后用要計算的數值作為數組的索引號,即可獲得其對應的十六進制數據。 3)Character.forDigit靜態方法可以將一個十六進制的數字轉變成其對應的字符表示形式,例如,根據數值15返回字符'F'。 源代碼://Demo47.java class hDemo { public static void main(String args[]) { int num = Integer.parseInt(args[0]); System.out.println("輸入的整數為:"+num); System.out.println("這個十進制整數對應的十六進制形式是:"); ten2Hex(num); } static void ten2Hex(int num) { StringBuffer sb = new StringBuffer(); char[] buf = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; for(int i=0; i<8; i++) { int temp = num&0x000000000f; sb.append(buf[temp]); num=num>>4; } sb.reverse(); System.out.println(sb); } } 運行結果:
一:java的基本語法
1.代碼都是存放在class里面的
2.嚴格區分大小寫(num NUM)是兩個不同的變量
3.格式自由.
4.單行注釋與多行注釋的和文檔注釋
5.標識符:
全部使用英文字母,駱駝式命名:從第二個單詞開始,每個單詞的首字母都要大寫,其它的小寫
(標識符不能為關鍵字,不能以數字開頭)
二:java中的變量
1.有八個原聲數據類型和引用數據類型.
2.類型轉換:
byte、short、char類型在運行過程中都會提升為int 類型(這樣的方式叫自動類型)我們可以將一個int類型強制轉換成byte、short、char類型 (需要強制類型轉換!顯示類型轉換丟失精度.
System.out.println('a'+1); 因為 1是int類型的,所以會升級為int 類型.
System.out.println(""+'a'+1);(任何數字和字符串相并且都自動轉換成字符串).
3.變量的生命周期:
在方法內定義的變量,當方法被調用的時候,變量被定義,當方法接收的時候。變量也會隨著方法釋放掉變量的作用域內是不可以重復定義,超出變量的作用域,變量將不能訪問.
三:java中的函數
1.定義:函數,又稱為方法,能夠完成某特定代碼的代碼塊,其個名字,方便于方法的調用函數的作用: 就是可以重復的去利用某一段代碼
2.函數必須有的: 函數名 返回值 返回值類型 (形式參數看需求而定)
3.形參:方法定義的形參相當于在方法中定義了一個局部變量,當這個方法被調用的時候,也就是對其方法里面的參數初始化啦!初始值為傳遞進來的參數
4.返回值類型:可以為任意一個類型,有一種特殊:當方法沒有返回值的時候,我們要把返回值類型定義為(void)
5.return :在方法中可以使用return 返回一個值,(返回的值必須是與返回值類型一致)
6.方法的重載:
多個函數具有相同的名字,參數的個數或者類型不同都可以. 返回值類型不能做衡量方法的重載
四:java中的運算符
1.算術運算符 % 取模,也叫做取余
++自增1,--自減1
++x 與x++的區別: 本質上是沒有區別的,x++是先參與運算再自加 ,而++x先自加一次才參與運算
在取模運算中,模數的符號會被忽略,被模數符號不能被忽略
2.賦值運算符 = 是賦值的意思
+= ,-=,*=,\=,%=
3.比較運算符號: == 是相互比較的意思
instanceof:判斷該對象是否是屬于指定的類型
4.邏輯運算符
&和&&的區別:
1. &&如果左邊為假,結果注定為假,右邊不參與運算
2.&如果左邊為假,結構注定為假,但是右邊會參與運算
|和||的區別:
1.如果左邊為真,結果注定為真,右邊不參與運算
2.如果左邊為真,結果注定為真,右邊參與運算
5.位運算符
&(與):真真得真,真假得假,假假得假
|(或):真假為真,真真為真,假假為假
^(異或):任何一個數與一個指定的數異或兩次,其結果等于本身,(第一個數異或第二個數 其結果再異或第二個.其結果等于它本身)(不同為1,相同為0)
移位運算符:
<<左移,砍掉高位,低位補0 一定要把它更改成32位。(左移N位相當于乘以2的N次方)
>>右移,砍掉低位,高位要看最高位的符號。符號位為1,就補1,符號位為0就補0(右移N位,相當于除以2的N次方)
6.switch
switch中的參數是必須是int類型的,但是byte,short,char都是隱式的自動類型提升啦~
break :結束循環
continue:提前結束本次循環,進入到下一次循環
總結:后期學習不認真!估計時間不安排好!!。。注意。
1 小算法復習: 2 /* 3 不用第三方變量交換兩個數的值 4 5 異或:第一個數異或第二個數,之后再把結果異或第二個數。其結果等于它本身! 6 7 1.<<最高位砍掉,最低位補零 8 (左移多少位,其實就是*2的N次方) 9 2.>>最低位砍掉.如果最高位是1,前面就是補1,否則補0 10 //(又移多少位,就是/2的N次方) 11 */ 12 13 class Demo 14 { 15 public static void main(String[] args) 16 { 17 int a = 3; 18 int b = 5; 19 20 a = a ^ b; 21 b = a ^ b; 22 a = a ^ b ; 23 System.out.println("a == "+a); 24 System.out.println("b =="+b); 25 26 } 27 } 28 /*某個培訓中心要為新到的學員安排房間,假設共有x個學員, 29 每個房間可以住6人,讓你用一個公式來計算他們要住的房間數 30 */ 31 32 33 class Demo 34 { 35 public static void main(String[] args) 36 { 37 int num = 48; 38 int homeNuber = getHomeNumber(num); 39 System.out.println("學生的個數為:"+homeNuber); 40 } 41 static int getHomeNumber(int num) //形式參數的初始化其實就是傳遞進來的參數幫他初始化啦~ 42 { 43 return (num+5)/6; //給一個最大的限度! 44 } 45 } 46 47 /* 48 利用無限循環實現0 - 9 之間的數之間的重復循環 49 */ 50 51 class Demo 52 { 53 public static void main(String[] args) 54 { 55 int x = 0; 56 while(true) 57 { 58 59 x = (x+1)%10; 60 System.out.println(x); 61 } 62 } 63 } 64 65 /* 66 利用小技巧把10進制轉換成2進制代碼! 67 */ 68 import java.io.*; 69 class Demo 70 { 71 public static void main(String[] args) throws Exception 72 { 73 //讀取鍵盤 74 BufferedReader br = 75 new BufferedReader(new InputStreamReader(System.in)); 76 System.out.println("本程序可以幫助您把十進制代碼轉換成二進制代碼:"); 77 String line = br.readLine(); 78 int num = Integer.parseInt(line); 79 StringBuffer sb = new StringBuffer(); 80 while(num>0) 81 { 82 int temp = num % 2; //獲取到除以2的余數! 83 sb.append(temp); 84 num = num / 2; 85 } 86 sb.reverse(); 87 System.out.println(sb); 88 } 89 } 90 91 92 /* 93 十進制轉換成十六進制之方法一。 94 */ 95 import java.io.*; 96 class Demo5 97 { 98 public static void main(String[] args) throws Exception 99 { 100 BufferedReader br = 101 new BufferedReader(new InputStreamReader(System.in)); 102 103 System.out.println("本程序可以通過十進制轉換成十六進制:"); 104 105 String line = br.readLine(); 106 int num = Integer.parseInt(line); 107 108 StringBuffer sb = new StringBuffer(); 109 while(num>0) 110 { 111 int temp = num % 16; 112 if(temp>9) 113 { 114 sb.append((char)(temp-10+'A')); 115 }else 116 { 117 sb.append(temp); 118 } 119 num = num / 16; 120 } 121 sb.reverse(); 122 System.out.println(sb); 123 } 124 } 125 126 127 /* 128 用移位的方法來求一個數 129 130 十進制轉換成十六進制 131 */ 132 import java.io.*; 133 class Demo 134 { 135 public static void main(String[] args) throws Exception 136 { 137 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 138 System.out.println("本程序可以幫助您從十進制轉換到十六進制:"); 139 String line = br.readLine(); 140 int num = Integer.parseInt(line); 141 Ten2Hex(num); 142 } 143 144 static void Ten2Hex(int num) 145 { 146 StringBuffer sb = new StringBuffer(); 147 int count = 0x00000000f; 148 for(int i = 0;i<8;i++) 149 { 150 int temp = num & count; 151 if(temp>9) 152 { 153 sb.append((char)((temp-10)+'A')); //類型要注意 154 } 155 else 156 { 157 sb.append(temp); 158 } 159 num = num >>4; 160 161 } 162 sb.reverse(); 163 System.out.println("結果為:"+sb); 164 } 165 } 166 167 /* 168 打印金字塔程序! 169 求算法的時候要注意: 170 找到求第一個的規律. 171 然后循環就可以。 172 */ 173 174 175 class Demo 176 { 177 public static void main(String[] args) 178 { 179 int n = 4; 180 for(int i = 0;i<n;i++) 181 { 182 for(int j = 0;j<n-i;j++) 183 { 184 System.out.print(" "); 185 } 186 for(int k =0;k<i*2-1;k++) 187 { 188 System.out.print("*"); 189 } 190 System.out.println(); 191 } 192 } 193 } 194 195 196 總結: 197 其實switch的參數必須是int類型的,為什么byte char short參數可以傳遞進來呢? 198 因為它的類型自動提升為int類型啦。也就是隱式的進行了強制轉換/所以是可以的.
一.java是一門高級的語言,具有跨平臺(一處編譯,到處運行)
1.javac 編譯源文件.java
2.運行源文件 java 啟動虛擬機
3.cls 清空dos界面文字!
4.java源文件 -->java.class(字節碼) -->windows(jvm) -->linux(jvm)
二:path環境變量
1.什么是path環境變量 ?path環境變量的作用?
解答:當我們運行一個exe可執行的文件的時候,系統會首先在當前的目錄下去尋找,尋找不到的時候就會在注冊表中尋找.如果沒有了最后才到path環境變量中尋找.
所以當我們想成功的在任何的目錄下運行javac 與java命令的時候,我們一定要把環境變量設置在path中.
2.查看path環境變量的兩種方式
解答:
第一種:我們可以通過在dos窗口里面輸入 set path命令查看path環境變量.
第二種:我們可以系統中查看到path環境變量的設置(圖形窗口里面)。
3.如何設置path環境變量
解答:
新建: JAVA_HOME: D:\java\jdk\(這部分內容是經常要修改的)
在path環境下面:%JAVA_HOME%bin;
4.%path% 的意義?
解答: 表示對path里面的做引用
java -version 表示查看當前的java版本好
class Path的作用:
類加載時,java虛擬機會在classpath指定的目錄下找相對應的class文件
在編譯時可以使用絕對路徑名,運行時則不能.
三.進制的轉換
1b = 8bit
1kb = 2^10b = 1024b
1mb = 102kb
1g = 1024mb
1t = 1024g
十進制轉換成二進制:
八進制轉換成二進制:
十六進制轉換成二進制:
將需要轉換的數字除以2,獲取到商和余數.將商繼續除以2,取到商為零.最后將所有的余數倒序排列.得到的就是該轉換出來的結果!
八進制轉換成二進制:
十進制轉換成二進制:除以2,直到商為零。將余數反轉
小數除以大數,則商為零。余數是小數本身
二進制轉換成十進制呢?
101
解題:
1*2^0 + 0*2^1+1*2^2 = 6;
2^0(相當于)沒有!
二進制轉換成八進制:每三個為一個整體 二進制轉換成十六進制的每4個位一個整體/
八進制轉換成十進制:
24
解題:
4*8^0+2*8^1 = 4+16 = 20
計算機的運行原理: 都是累加器的
5 - 5 其實在計算機中運行效果是: 5+(-5)
負數是如何表示的?
原碼 取反 反碼 加1 補碼
總結:
如何將二進制,八進制 ,十六進制轉換成十進制呢?
12F 轉換成十進制:
15*16^0+2*16^1+1*16^2 = 15+ 32 + 256 = 303 其實就是12f
都是采用乘法。
如果將十進制轉換成二進制,十六進制 八進制呢?
都是采用除法,取余.
關于原碼,反碼與補碼:
-5 原碼: 101
反碼: 010
補碼: 011
因為是32位所以: 1111 1111 1111 1111 1111 1111 1111 1011
1 class Test2 2 { 3 public static void main(String[]args) 4 { 5 StringBuffer sb = new StringBuffer(); 6 int num = 1234; 7 while(num>0) 8 { 9 int temp = num % 16; 10 if(temp>9) 11 { 12 sb.append((char)temp-10+'A'); 13 } 14 else 15 { 16 sb.append(temp); 17 } 18 num = num / 16; 19 } 20 System.out.println(sb); 21 22 } 23 }
個人總結:
總體來說今天的學習認真度還是很不夠的!咱們要注意的地方就是:學習的時候不能分心.小細.一定不要輸給別人看.