面向過程思想java
面向對象思想編程
對於描述複雜的事物,爲了從宏觀上把握,從整理上合理分析,咱們須要使用面向對象的思路來分析整個系統。可是,具體到微觀操做,仍然須要面向過程去處理。安全
面向對象編程(Object-Oriented Programming,OOP)dom
面向對象編程的本質是:以類的方式組織代碼,以對象的組織(封裝)數據ide
抽象oop
三大特性:學習
從認識角度考慮是先有對象後有類。對象,是具體的事物。類,是抽象的,是對對象的抽象測試
從代碼運行角度考慮是先有類後有對象。類是對象的模板。this
1.該露的露,該藏的藏設計
2.封裝(數據的隱藏)
⭐️屬性私有,get/set
Student類
package com.oop.demo04; //類 private:私有 public class Student { //屬性私有 private String name;//名字 private int id;//學號 private char sex;//性別 private int age;//年齡 //提供一些能夠操做這個屬性的方法 //提供一些public的get、set的方法 //get得到這個數據 public String getName(){ return this.name; } //set給這個數據設置值 public void setName(String name){ this.name = name; } //alt+insert 自動生成get、set方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { if(age>120 || age<0){ this.age=3; }else{ this.age = age; } } /* 1.提升程序的安全性,保護數據 2.隱藏代碼的實現細節 3.統一接口 4.系統可維護性增長了 */ }
測試類
package com.oop; import com.oop.demo03.Pet; import com.oop.demo04.Student; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { Student s1 = new Student(); s1.setName("沈小榆"); System.out.println(s1.getName());//沈小榆 s1.setAge(999);//不合法的 3 System.out.println(s1.getAge());//3 } }
繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模
extands的意思是「擴展」。子類是父類的擴展
Java中類只有單繼承,沒有多繼承:一個兒子只有一個爸爸,一個爸爸能夠有多個兒子
繼承是類和類之間的一種關係。除此以外,類和類之間的關係還有依賴、組合、聚合等
繼承關係的兩個類,一個爲子類(派生類),一個爲父類(基類)。子類繼承父類,使用關鍵字extends來表示
子類和父類之間,從意義上講應該具備「is a」的關係
object 類:在java中全部的類,都默認直接或者間接繼承Object
super注意點:
super和this對比
表明的對象不一樣:
前提:
構造方法的區別:
父類Person類
package com.oop.demo05; //在java中全部的類,都默認直接或者間接繼承Object //Person 人:父類 public class Person /*extends Object*/{ private int money =10_0000_0000; protected String name ="shenxiaoyu"; public void say(){ System.out.println("Person"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public Person() { System.out.println("Person無參執行了"); } }
子類Student類
package com.oop.demo05; //Student is Person 學生是人 //子類繼承了父類就會擁有父類的所有方法,私有的東西沒法被繼承 public class Student extends Person { //ctrl+H能夠查看繼承樹 private String name ="moguyu"; public void test1(String name){ System.out.println(name); System.out.println(this.name); System.out.println(super.name); } public void say(){ System.out.println("Student"); } public void test2(){ say();//Student this.say();//Student super.say();//Person } public Student() { //隱藏代碼:調用了父類的無參構造 super();//調用父類的構造器,必需要在子類構造器的第一行 //this()調用本身的構造器也須要放在代碼的第一行 System.out.println("Student無參執行了"); } }
測試類
package com.oop; import com.oop.demo03.Pet; import com.oop.demo05.Person; import com.oop.demo05.Student; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { Student student = new Student(); /* Person無參執行了 Student無參執行了 */ student.say(); student.test1("沈小榆"); /* 沈小榆 moguyu shenxiaoyu */ student.test2(); } }
須要有繼承關係,子類重寫父類的方法
重寫,子類的方法和父類必須保持一致:方法體不一樣!
static方法,屬於類,它不屬於實例,不能被重寫
final 常量,被final修飾的也不能重寫 類若是被final,則他不能被繼承--->final以後斷子絕孫
private方法,私有,也不能重寫
重寫的意義:
Alt+Insert:override
父類B類
package com.oop.demo05; //重寫都是方法的重寫,和屬性無關 public class B { public void test1(){ System.out.println("B=>test()"); } public static void test2() { System.out.println("B=>test()"); } }
子類A類
package com.oop.demo05; //繼承 public class A extends B{ @Override//註解:有功能的註解 //Override 重寫 public void test1() { System.out.println("A=>test()"); } public static void test2() { System.out.println("A=>test()"); } }
測試類
package com.oop; import com.oop.demo05.A; import com.oop.demo05.B; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //靜態方法的和非靜態方法區別很大 //靜態方法:方法的調用只和左邊,定義的數據類型有關 //重寫只和非靜態方法有關 A a = new A(); a.test1();//A=>test() a.test2();//A=>test() //父類的引用指向了子類 B b = new A(); b.test1();//A=>test() 子類重寫了父類的方法 b.test2();//B=>test() } }
即同一方法能夠根據發送對象的不一樣而採用多種不一樣的行爲方式
一個對象的實際類型是肯定的,但能夠指向對象的引用的類型有不少
多態存在的條件
注意:
父類Person類
package com.oop.demo06; public class Person { public void run(){ System.out.println("run"); } }
子類Student類
package com.oop.demo06; public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
測試類
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //Student student = new Student(); //new Person(); //一個對象的實際類型是肯定的 //能夠指向的引用類型就不肯定了:父類的引用指向子類 //Student 能調用的方法都是本身的或者父類的! Student s1 = new Student(); //Person 父類型,能夠指向子類,可是不能調用子類獨有的方法 Person s2 = new Student(); Object s3 = new Student(); //對象能執行哪些方法,主要看對象的類型和右邊關係不大 s2.run();//son 子類重寫了父類的方法,執行了子類的方法 s1.run();//son s1.eat(); } }
instanceof:用來查看能不能經過編譯
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; import com.oop.demo06.Teacher; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //Object>person>Student //Object>person>Teacher Object object = new Student(); //System.out.println(X instanceof Y);能不能編譯經過 System.out.println(object instanceof Student);//true System.out.println(object instanceof Person);//true System.out.println(object instanceof Object);//true System.out.println(object instanceof Teacher);//false System.out.println(object instanceof String);//false System.out.println("==================================="); Person person = new Student(); System.out.println(person instanceof Student);//true System.out.println(person instanceof Person);//true System.out.println(person instanceof Object);//true System.out.println(person instanceof Teacher);//false //System.out.println(person instanceof String);編譯報錯 System.out.println("==================================="); Student student = new Student(); System.out.println(person instanceof Student);//true System.out.println(person instanceof Person);//true System.out.println(person instanceof Object);//true //System.out.println(person instanceof Teacher);編譯報錯 //System.out.println(person instanceof String);編譯報錯 } }
類型轉化
子類Student類
package com.oop.demo06; public class Student extends Person{ public void go(){ System.out.println("go"); } }
測試類
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; import com.oop.demo06.Teacher; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //類型之間的轉化:父類 子類 //高 ------->低 須要強制轉換 Person obj = new Student(); //student將這個對象轉換爲Student類型,咱們就可使用Student類型的方法了 Student student = (Student) obj; student.go();//((Student) obj).go(); Person person = student; } }
修飾符和返回類型
package com.oop.demo01; //Demo01 類 public class Demo01 { //main方法 public static void main(String[] args) { } /* 修飾符 返回值類型 方法名(...){ //方法體 return 返回值; } */ public String sayHello(){ return "hello,world!"; } public void hello(){ return; } public int max(int a,int b){ return a>b ? a : b;//三元運算符 } }
break和return區別
方法名:注意規範!見名知意
參數列表:(參數類型,參數名)....
異常拋出
靜態方法和非靜態方法
Demo02類
package com.oop.demo01; public class Demo02 { public static void main(String[] args) { Student.say(); //實例化這個類 new //對象類型 對象名 = 對象值 Student student = new Student(); student.said(); } }
Student類
package com.oop.demo01; //學生類 public class Student { //靜態方法 static public static void say(){ System.out.println("學生說話了"); } //非靜態方法 public void said(){ System.out.println("學生說過話了"); } }
static方法和static方法能相互調用,非靜態方法和非靜態方法能相互調用。非靜態方法裏能夠直接調用靜態方法,可是,靜態方法裏不能直接調用非靜態方法:
//和類一塊兒加載的 public static void a(){ b(); //不能直接調用c()和d() } public static void b(){ a(); //不能直接調用c()和d() } //類實例化以後才存在 public void c(){ a(); b(); d(); } public void d(){ a(); b(); c(); }
形參和實參
package com.oop.demo01; public class Demo03 { public static void main(String[] args) { //形式參數和實際參數的類型要對應 Demo03 demo03 = new Demo03(); int add = demo03.add(1,2);//實際參數 System.out.println(add); } public int add(int a,int b){//形式參數 return a+b; } }
值傳遞和引用傳遞
值傳遞:
package com.oop.demo01; //值傳遞 public class Demo04 { public static void main(String[] args) { int a = 1; System.out.println(a);//1 Demo04.change(a); System.out.println(a);//1 } //返回值爲空 public static void change(int a){ a=10; } }
引用傳遞:
package com.oop.demo01; //引用傳遞 public class Demo05 { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name);//油炸蘑菇魚 Demo05.change(person); System.out.println(person.name);//沈小榆 } public static void change(Person person){ //person是一個對象:指向的----> Person person =new Person(); 這是一個具體的人,能夠改變屬性! person.name = "沈小榆"; } } //定義了一個Person類,有一個屬性:name class Person{ String name="油炸蘑菇魚"; }
this關鍵字
類是一種抽象的數據類型,它是對某一類事物總體描述/定義,可是並不能表明某一個具體的事物
對象是抽象概念的具體實例
使用new關鍵字建立對象
使用new關鍵字建立的時候,除了分配的內存空間以外,還會給建立好的對象進行默認的初始化以及類中構造器的調用
Student類:
package com.oop.demo02; //學生類 public class Student { //屬性:字段 String name; int age; //方法 public void study(){ System.out.println(this.name+"在學習"); } }
Application類:
package com.oop.demo02; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //類:抽象的,須要實例化 //類實例化後會返回一個本身的對象 //xiaoyu對象就是一個Student類的具體實例 Student xiaoyu = new Student(); Student xiaofu = new Student(); xiaoyu.name="魚魚"; xiaoyu.age=6; xiaofu.name="付付"; xiaofu.age=9; System.out.println(xiaoyu.name);//魚魚 System.out.println(xiaoyu.age);//6 System.out.println(xiaofu.name);//付付 System.out.println(xiaofu.age);//9 } }
構造器詳解
類中構造器也稱爲構造方法,是在進行建立對象的時候必需要調用的。而且構造器有如下兩個特色:
public class Person { public Person() { } }
構造器做用:
注意點:
Person類
package com.oop.demo02; //java---> class public class Person { //一個類即便什麼都不寫,它也會存在一個方法,這個方法就是構造方法 //顯示的定義構造器 String name; //實例化初始值 //1.使用new關鍵字,本質是在調用構造器 //2.用來初始化值 public Person(){ this.name="小魚魚";//this.是當前的值,=後面是構造器傳進來的值 } //有參構造:一旦定義有參構造,無參構造必須顯示定義 public Person(String name){ this.name=name; } //Alt+Inset會生成構造器 constructor--->--->0k---->有參 //Alt+Inset會生成構造器 constructor--->--->select none---->無參 }
測試類
package com.oop.demo02; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { //new實例化了一個對象 Person person = new Person(); Person person1 = new Person("XIAOYUYU"); System.out.println(person.name);//小魚魚 System.out.println(person1.name);//XIAOYUYU } }
Pet類
package com.oop.demo03; public class Pet { public String name;//public能夠在不在一個包的時候也能調用 public int age; //無參構造 public void shout(){ System.out.println("叫了一聲"); } }
Application類
package com.oop; import com.oop.demo03.Pet; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { Pet dog = new Pet(); dog.name ="火鍋"; dog.age=3; System.out.println(dog.name); System.out.println(dog.age); Pet cat = new Pet(); } }
內存分析圖片:
類與對象
對象的屬性:字段field 成員變量
默認初始化:
數字:0 0.0
char:u0000
oolean:false
引用:null
定義:
對象的建立和使用
類裏有
package com.oop.demo07; //static public class Student { private static int age;//靜態變量 private double score;//非靜態變量 public void run(){ } public static void go(){ } public static void main(String[] args) { Student s1 = new Student(); System.out.println(age); //System.out.println(Student.score);非靜態變量不能直接調用 System.out.println(s1.age); System.out.println(s1.score); go(); s1.run(); } }
package com.oop.demo07; public class Person { /* { //代碼塊(匿名代碼塊) } static{ //靜態代碼塊 } */ //2:賦初始值 { System.out.println("匿名代碼塊"); } //1 只執行一次 static{ System.out.println("靜態代碼塊"); } //3 public Person() { System.out.println("構造方法"); } public static void main(String[] args) { Person p1 = new Person(); /* 靜態代碼塊 匿名代碼塊 構造方法 */ System.out.println("============="); Person p2 = new Person(); /* 匿名代碼塊 構造方法 */ } }
package com.oop.demo07; import static java.lang.Math.random;//靜態導入包 import static java.lang.Math.PI; public class Test { public static void main(String[] args) { System.out.println(random()); System.out.println(PI); } }
abstract修飾符能夠用來修飾方法也能夠修飾類,那麼該方法就是抽象方法;若是修飾類,那麼該類就是抽象類
抽象類中能夠沒有抽象方法,可是有抽象方法的類必定要聲明爲抽象類
抽象類,不能使用new關鍵字來建立對象,它是用來讓子類繼承的
抽象方法,只有方法的聲明,沒有方法的實現,它是用來讓子類實現的
父類Action類
package com.oop.demo08; //abstract 抽象類 extends 單繼承 接口能夠多繼承 public abstract class Action { //約束——有人幫咱們實現 //abstract,抽象方法,只有方法名字,沒有方法的實現 public abstract void doSomething();//有抽象方法必定要聲明抽象類 //1.不能new這個抽象類,只能靠子類去實現它:約束! //2.抽象類中能夠寫普通方法 //3.抽象方法必須寫在抽象類中 }
子類A類
package com.oop.demo08; //抽象類的全部方法,繼承了他的子類,都必需要實現他的方法,除非子類也是abstract public class A extends Action{ @Override public void doSomething() { } }
子類繼承抽象類,那麼就必需要實現抽象類沒有實現的抽象方法,不然該子類也要聲明爲抽象類
抽象類存在的意義:提升開發效率
普通類:只有具體實現
抽象類:具體實現和規範(抽象方法)都有
接口:只有規範!本身沒法寫方法!約束和實現分離!
接口就是規範,定義的是一組規則,體現了現實世界中「若是你是...則必須能...」的思想。若是你是天使,則必須能飛。
接口的本質就是契約,就像咱們人間的法律同樣。制定好後你們都遵照
OO的精髓就是對對象的抽象,最能體現這一點的就是接口。
聲明類的關鍵字是class,聲明接口的關鍵字是interface
UserService接口:
package com.oop.demo09; //interface 定義的關鍵字,接口都須要有實現類 public interface UserService { //接口中全部的屬性是 public static final int AEG = 99; //接口中全部的定義的方法其實都是抽象的 public abstract void add(String name); void delete(String name); void update(String name); void query(String name); }
TimeService接口:
package com.oop.demo09; public interface TimeService { void timer(); }
UserServiceImpl類用來實現接口:通常命名爲接口名+Impl
package com.oop.demo09; //抽象類: extends //類能夠實現接口 implements 接口 //實現了接口的類,就須要重寫接口的方法 //利用接口實現多繼承 public class UserServiceImpl implements UserService,TimeService{ @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } @Override public void timer() { } }
接口的做用:
內部類就是在一個類內部定義一個類。好比,A類中定義一個B類,那麼B類就是A類的內部類,A類就是B類的外部類
Outer類:內部類能夠得到外部類的私有屬性
package com.oop.demo10; public class Outer { private int id=10; public void out(){ System.out.println("這是外部類的方法"); } public class Inner{ public void in(){ System.out.println("這是內部類的方法"); } //得到外部類的私有屬性 public void getID(){ System.out.println(id); } } public void method(){ //局部內部類 class Inner{ public void in(){ } } } } //一個java類中能夠有多個class類,但只能有一個public class類 class A{ }
測試類:經過這個外部類來實例化內部類
package com.oop; import com.oop.demo10.Outer; //一個項目應該只存在一個main方法 public class Application { public static void main(String[] args) { Outer outer = new Outer(); //經過這個外部類來實例化內部類 Outer.Inner inner = outer.new Inner(); inner.in();//這是內部類的方法 inner.getID();//10 } }
Test類:沒有名字初始化類,不用將實例保存在變量中
package com.oop.demo10; public class Test { public static void main(String[] args) { //沒有名字初始化類,不用將實例保存在變量中 new Apple().eat(); new UserService(){ @Override public void hello() { } }; } } class Apple{ public void eat(){ System.out.println("1"); } } interface UserService{ void hello(); }