本文主要是介紹一下java面向對象編程方面的知識,涉及的內容可能有點多,因此可能會感受比較籠統,詳細請參見《Java編程思想》裏面比較具體點。java
1.面向對象編程
和遵循設計原則和設計模式,設計模式
目標都是爲了消除程序中的重複代碼socket
重複代碼通常是放在父類中的函數
Dog dog=new Dog()this
左邊是建立一個Dog的引用,右邊是建立Dog的一個對象,這個過程是對象實例化也就是把對象的賦值給引用(至關於建立了一個結構體變量並進行了初始化)spa
建立對象就至關於給結構體進行初始化,建立後除了分配了內存,構造函數被調用,其中的方法也能夠被調用了(除了加了static的方法,由於加了是靜態的,就不須要建立也能調用了),至關於結構體裏面的函數指針對初始化了,能夠被使用了線程
2.super和this設計
簡單理解,super是指向父類的,this是指向當前類(對象)的,指針
(super.xx是調用父類的方法,this.xx是調用子類當前類的方法)
3. 抽象類和抽象函數
抽象函數裏面是沒有函數體的,定義抽象函數必須是在抽象類裏面,
可是抽象函數能夠給子類使用進行復寫(關鍵字@ overwrite)
(子類對父類中的函數進行復寫),
建立一個對象就分配了內存,同時就會自動調用了構造函數,當子類建立對象時,父類必須也是建立了對象的(爲了保證子類建立對象父類也建立了對象調用了構造函數,子類的構造函數中加一個super()就會去調用父類的構造函數,對父類進行了對象建立),
因此雖然抽象類是不能夠被建立對象的,可是抽象類的子類建立對象後,抽象類就會被建立了抽象函數,同時父類的構造函數也就會被調用(等於自動在子類的構造函數中加了super())
4.包(軟件包)
就是相同名字的類放在不一樣的文件夾,一個包裏就是一個文件夾裏有類
在類的前面加一行打包關鍵字,表示當前的類放在一個包裏
執行的時候要注意,帶上包名,即包名.類名
包名都要小寫,
package org.mars 就會生成一級級的目錄,也就是先org而後裏面是mars目錄而後裏面纔是類
5.接口(相似C中的鉤子函數)---很重要
特殊的類,特殊的抽象類,裏面全是抽象函數,使用interface定義,省略了class,
同時抽象函數都是Public權限(即便寫了其餘的也是public)的
經過繼承接口(類),來複寫抽象函數,而後生成子類的對象
class usbphone implements USB{
}
使用implements再也不是extends,這裏繼承接口(特殊的繼承),也叫實現接口(要複寫抽象函數),由於接口裏面都是抽象的並無具體
例子:
interface Usb{
public void read();
public void write();
}
定義子類實現:
class Phone implements Usb{
public void read(){
system.out.println();
}
public void write(){
system.out.println();
}
}
使用方法
class Test{
public static main(String args[]){
Phone phone=new Phone();
Usb usb =phone;//向上轉型:把子類的對象賦值給父類的引用
usb.read();//這樣父類對象就實例化了,父類中的函數就能夠被調用了
}
}
向上轉型:把子類的對象賦值給父類的引用
一個類只能有一個父類,單繼承
可是一個類能夠實現多個接口,一個接口能夠繼承多個接口
一個類能夠實現多個接口:
interface WiFi{
void open();
void read();
}
class Phone implements Usb,WiFi{
public void read(){
system.out.println();
}
public void write(){
system.out.println();
}
public void open(){
system.out.println();
}
public void write(){
system.out.println();
}
}
class Test{
public static main(String args[]){
Phone phone=new Phone();
Usb usb =phone;//向上轉型:把子類的對象賦值給父類的引用
usb.read();//這樣父類對象就實例化了,父類中的函數就能夠被調用了
WiFi wifi =phone;//向上轉型:把子類的對象賦值給父類的引用
wifi.close();//這樣父類對象就實例化了,父類中的函數就能夠被調用了
}
}
一個接口能夠繼承多個接口:這裏是繼承不是實現,由於沒有複寫
interface A{
void funa();
}
interface B{
void funb();
}
interface C extends A,B{//這樣C中就包含A,B中的方法,當實現C的時候就要複寫A,B中的,也就是三個方法都要複寫
void func();
}
6.工廠設計模式:
Class Test{
public static main(String args[]){
Printer printer=null;//類來建立對象(一個引用 左邊),對象等於null就是還未實例化,對象等於new出來空間的地址或者等於一個地址就是對象的實例化(得到實例化對象)
int flag=1;
if(flag==0)
printer=new HpPrint();//向上轉型
else if(flag==1)
printer=new CanPrint();
printer.open();//因爲向上轉型了,父類對象實例化了,因此父類中的方法能夠調用了
printer.print("ets");
printer.close();
}
}
可是這個程序還有問題,當不斷添加打印機就要不斷對該打印機類型的對象實例化,並增長if else 若是不少個增長就麻煩了,代碼不少。。。
通常對於重複代碼,就是封裝到函數裏,而後來調用,能夠經過參數來得到想要的,好處就是不用每次出現這段代碼的地方都修改,而是隻是修改函數裏面的就能夠了:(這就是所謂的工廠設計模式,須要的時候給參數到工廠,而後工廠根據你給的參數生產出你要的)
還有好處,對於使用者不知道內部有哪些子類,也不用關心內部有那些子類,對於開發來講就能夠對於子類隨時能夠刪除修改一下工廠就行了,外部提供的地方不用修改
Class Printfactory{
public static Print getPrinter(int flag){
Printer printer=null;//類來建立對象(一個引用 左邊),對象等於null就是還未實例化,對象等於new出來空間的地址或者等於一個地址就是對象的實例化(得到實例化對象)
int flag=1;
if(flag==0)
printer=new HpPrint();//向上轉型
else if(flag==1)
printer=new CanPrint();
return printer;
}
}
Class Test{
public static main(String args[]){
int flag=1;
Printer priner=Printfactory.getPrinter(flag);
printer.open();//因爲向上轉型了,父類對象實例化了,因此父類中的方法能夠調用了
printer.print("ets");
printer.close();
}
}
7.異常 (有點相似中斷)
JAVA中全部東西都是對象,同理異常也是一個對象
產生事件,就會生成一個異常對象
有可能出現異常的代碼放在TRY裏面,處理異常代碼放在catch,finally裏面主要是放一些釋放資源的代碼
try裏面出現異常就會執行catch裏面的代碼,沒出現異常就不會執行catch裏面的代碼,finally裏面的代碼無論出現不出現都會執行
throw ,throws拋出異常
class User{
private int age;
public void setAge(int age){
if(age<0)
{
RuntimeException e=new RuntimeException("年齡不能爲負數");//建立一個異常對象(屬於unChecked Exception,不須要用try catch處理,若是是Exception和它的子類除了RuntimeException,用這些checkedException就須要用try catch處理,若是還不想使用try catch,就加聲明也就是throws,讓誰調用誰處理)
throw e;//拋出這個異常對象,當JAVA虛擬機收到這個異常對象,會終止這個程序運行,並打印
}
this.age=age;
}
}
class User{
private int age;
public void setAge(int age)throws Exception{//checkException還不想使用try catch,就加聲明也就是throws,讓誰調用誰處理)
if(age<0)
{
Exception e=new Exception("年齡不能爲負數");//建立一個異常對象
throw e;//拋出這個異常對象,當JAVA虛擬機收到這個異常對象,會終止這個程序運行,並打印
}
this.age=age;
}
}
調用的地方處理:
class Test{
public static main(String args[]){
User user=new User();
try{
user.setAge(-20);
}
catch(Exception e){
system.out.println(e);
}
}
}
8.JAVA當中的IO
InputStrem OutputStream是因此字節流的父類,都是抽象類
子類有
FileInputStream FileOutputStream
例如:
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
InputStream mmInStream = null;
mmInStream = socket.getInputStream();
if( (bytes = mmInStream.read(buffer)) > 0 )
{
byte[] buf_data = new byte[bytes];
for(int i=0; i<bytes; i++)
{
buf_data[i] = buffer[i];
}
String s = new String(buf_data);
ForView.setText(s);
}
mmInStream.close();
9. 內部類和匿名內部類
內部類:
定義在一個類的裏面:
假設B定義在A裏面:
A a=new A();
內部類則是:
A.B b=new A().new B();
this默認是當前類的成員,若是使用外部類就要A.this.i這樣來
匿名內部類:
是內部類,可是沒有名字
class B{
public void fun(A a){
System.out.println();
a.doSomething();
}
}
class Test{
public static main(String args[]){
B.b=new B();
b.fun(new A(){//這裏就是一個類,匿名內部類,至關於這裏定義一個實現A接口的子類,這樣A就能夠NEW出來了
public void dosomething(){
System.out.println();
}
})
}
}
10.線程:
class FirstTread extends Thread{
public void run(){
system.out.println();
}
}
class Test{
public static main(String args[]){
FirstTread firstthread=new FirstTread();//建立線程
firstthread.start()//線程就緒運行
}
}
第二種方法:(因爲繼承只能使用一次,因此能不用就不用,因此第二種用的多些)
class Runnabletmp implements Runnable{
public void run(){
}
}
class Test{
public static main(String args[]){
Runnable runable=new Runnable();//生成一個實現接口的對象
Tread t=new Thread(runnable);//並將對象傳進去(至關於結構體變量傳進去)
t.start();
}
}
控制函數:
Tread.sleep() Thread.yield()
getPriority() setPriority();
線程最大優先級10最小1,可使用Thread.裏面提供的靜態常量當參數進行設置