面向物件2
訪問修飾符
| private | default | protected | public | |
|---|---|---|---|---|
| 當前類 | ?? | ?? | ?? | ?? |
| 同一個包 | ?? | ?? | ?? | ?? |
| 不同包 | ?? | ?? | ?? | ?? |
| 無關類 | ?? | ?? | ?? | ?? |
引數傳遞
基本型別和String型別的引數傳遞(值傳遞)
? 在進行基本型別的引數傳遞是,傳的是引數的值,并不是引數本身!當main方法呼叫其他方法時,改變的只是被呼叫的方法的引數,與main方法內的引數無關,當方法執行結束后,所有的引數物件都會被gc自動銷毀回收,
參考型別的引數傳遞(記憶體地址傳遞)
? 參考資料型別非常多,大致包括:
? 類、 介面型別、 陣列型別、 列舉型別、 注解型別
? 在進行參考型別的引數傳遞是,傳的是參考型別的引數地址!當main方法呼叫其他方法時,進行操作的是賣弄傳進來的地址,當方法執行結束后,并不影響更改后的引數物件,
public class Test01 {
public static void test(int a, int[] arr){
a = 3;
int[] arr1 ={5,4,3,2,1};
arr[0] = 10;
arr = arr1;
}
public static void main(String[] args) {
int[] arr={1,2,3,4,5};
int a = 0;
test(a,arr);
System.out.println(arr[0]);
}
}
// 輸出的結果:
// a = 0;
// arr = {10,2,3,4,5};
final常量
特點
- 被final修飾的類不可以被繼承
- 被final修飾的方法被不可以被重寫
- 被final修飾的變數不可以更改值
- 被final修飾的參考不可以存盤其他物件的記憶體地址
封裝
封裝的目的
提供一個統一的用來設定物件屬性和訪問物件屬性的入口
封裝的要求
- 所有成員的變數全部私有
- 需要提供公有的set和get方法來提供物件成員變數的訪問
- 需要提供一個無參構造方法(必須是public所修飾的)用來給外界創建物件
Java Bean
? 想象一下存在這樣一個箱子,其內部被分割成幾個格子,每個格子用來存放特定的物品,工人取出或者放入物品后封箱,然后叫了個快遞把箱子發出去了,這個箱子就是 Java Bean 啊,取出、放入就是getter、setter,物品就是屬性,封箱發出就是序列化和傳輸,
// 舉個栗子
public class Product {
private int id;
private String name;
private double price;
private double stock;
public Product(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getStock() {
return stock;
}
public void setStock(double stock) {
this.stock = stock;
}
}
繼承(Java中只支持單繼承)
? Java種的繼承解決的是代碼復用的問題(父類:共性抽取,子類:功能表現-功能拓展)
? 每一個類都只能有一個父類,但是可以有許多子類
繼承帶來的好處
- 提高了代碼的復用性,提高了軟體開發的效率
- 繼承的出現讓類和類之間產生了關系,提供了多型的前提
// 舉個一個栗子
// 新建一個父類Person
public class Person {
public String name;
public int age;
public void eat(){
System.out.println("Person => eat()");
}
}
// 新建一個子類Student繼承Person
public class Student extends Person{
public int sno;
public void study(){
System.out.println("Student => study()");
}
}
// 新建一個子類Teacher繼承Person
public class Teacher extends Person{
public int tno;
public void teach(){
System.out.println("Teacher => teach()");
}
}
// 主運行類,Student實體化的物件,擁有Person類里的引數和方法
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "student01";
student1.sno = 10001;
student1.eat();
student1.study();
}
繼承里的構造方法
當new了子類新物件的時候(即對子類物件進行初始化的時候),父類的構造方法也會執行,且其優先級在子類的構造方法之前,因此父類必須擁有無參構造!
(?)對于子類的構造方法而言,不管是子類的是有參構造方法,還是無參構造方法,都是默認呼叫父類的無參構造方法,所以不管父類的構造方法是否有做物件的初始化,都必須將父類的無參構造方法給顯式的定義出來
super 的三種用法
- 在子類的構造方法種的第一行,用來訪問父類的指定建構式,如果不寫,則默認訪問父類的無參構造
- 在子類中有和父類名字相同的成員變數時,用于訪問父類的指定成員變數(阿里編程規范里不允許使用)
- 在子類有和父類完全相同的方法的時候(方法名相同&引數的數量,順序,型別相同),訪問父類的方法
this 的三種用法
- 在當前子類的構造方法時,會呼叫自己的其他構造方法
- 訪問自己的成員變數
- 訪問當前類的其他方法
// 舉個一個栗子
// 新建一個父類Person
public class Person {
public String name;
public int age;
// 重寫無參構造
public Person(){
System.out.println("Person => Person()");
}
// 重寫有參構造
public Person(String name, int age) {
System.out.println("Person => Person(name,age)");
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("Person => eat()");
}
}
// 新建一個子類Student繼承Person
public class Student extends Person{
public int sno;
// 重寫無參構造
public Student(){
super(); // 呼叫父類的無參構造,如果不寫默認生成
System.out.println("Student => Student()");
}
// 重寫有參構造
public Student(String name, int age, int sno) {
super(name, age);// 呼叫父類的有參構造,如果不寫默認呼叫無參構造,會爆紅!!!!!!!
this.sno = sno;
}
public void study(){
System.out.println("Student => study()");
}
}
// 主運行類,Student實體化的物件時,先呼叫父類Person的無參構造,再呼叫自己的構造方法
public static void main(String[] args) {
// 通過子類的無參構造,實體化物件(父類無參構造 => 子類無參構造)
Student student1 = new Student();
// 通過子類的有參構造,實體化物件(父類有參構造 => 子類有參構造)
Student student2 = new Student("Robot01",18,10001);
}
@Override注解
-
宣告當前方法重寫了父類方法
-
如果被標記的方法沒有重寫父類方法,編譯則無法通過
// 新建一個父類Person
public class Person {
public String name;
public int age;
public void eat(){
System.out.println("Person => eat()");
}
}
// 新建一個子類Student繼承Person
public class Student extends Person{
public int sno;
public void study(){
System.out.println("Student => study()");
}
@Override
public void eat(){
System.out.println("Student => eat()");
}
}
抽象類(abstract)
抽象類的概念
? 抽象類是用來捕捉子類的通用性的,它不能被實體化,只能用作子類的超類,抽象類是被用來創建子類的模板,如果父類中的方法無法滿足所有子類的需求,這個方法就應該是一個抽象方法
抽象類的特點
- 抽象類本身不可以使用new 創建物件
- 必須通過子類來創建物件
- 子類必須覆寫父類當中所有的抽象方法
- 抽象類中可以定義非抽象方法,用于給子類繼承使用,自己無法呼叫
- 抽象類中可以定義成員變數,用于給子類繼承使用,自己同樣無法呼叫
- 抽象類中可以定義構造方法,用于給子類繼承使用,自己同樣無法使用
- 抽象類中可以不定義抽象方法
- 如果一個類繼承了抽象類,卻沒有覆寫父類的所有抽象方法,那么這個類,一定也是一個抽象類
抽象類實作
// 新建抽象類Pic,定義抽象方法area()
public abstract class Pic {
public abstract void area();
}
// 新建類TriAngle,覆寫抽象方法area()
public class TriAngle extends Pic {
@Override
public void area() {
System.out.println("TriAngle => area()");
}
}
// 新建主運行類,測驗代碼
public static void main(String[] args) {
TriAngle triAngle = new TriAngle();
triAngle.area();
}
介面(interface)(變向實作多繼承)
介面的概念
? 介面相比抽象類,抽象的更加徹底,介面只能描述子類所應當具備的方法,但是沒有具體的實作,將功能的定義和實作進行分離,給程式解耦
? 在 JDK1.7 之后介面中可以定義常量,在 JDK1.8 之后介面中可以定義帶有方法體的默認方法(default)和靜態方法(static),所有版本中都不可以定義普通方法,也不可以定義建構式,成員變數
介面的特點
- 允許多實作(相當于多繼承)
- 不允許定義成員變數和非抽象方法
- 可以定義抽象方法和靜態常量
- 介面相當于是功能的集合
// 定義介面
public interface Brake {
void brakeRole();
}
public interface EnvironmentProtect {
void emission();
}
public interface Safe {
void safeRule();
}
// 定義類Car繼承介面
public class Car implements Brake,EnvironmentProtect,Safe{
@Override
public void brakeRole() {
System.out.println("Brake => breakRole()");
}
@Override
public void emission() {
System.out.println("EnvironmentProtect => emission()");
}
@Override
public void safeRule() {
System.out.println("Safe => safeRule()");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548565.html
標籤:Java
下一篇:day02-功能實作02
