本文是基于樓主學習韓順平老師java課后的筆記整理而來 分享出來 希望能跟大家一起交流 共同進步~
為了秋招 沖沖沖!
緒論
java有一個重要的特性是面向物件(oop)
這是它與其他語言重要的差別之一 也是它如此受市場歡迎的重要原因
本文我們就來簡單說說 封裝繼承多型這三大面向物件重要特征
封裝
一 封裝是什么
簡而言之,封裝就是把抽象出來的資料【屬性】和對資料的操作【方法】封裝在一起
資料被保護在內部 程式的其他部分只有通過被授權的方法 才能對資料進行操作
類似電視機 中我們只能用遙控器控制聲音大小 亮度增減 但是并不知道它內部是怎么實作的 也不用知道
這點就可以看出面向物件的好處了 不同于c面向程序注重功能的具體實作 java擁有非常強大的類別庫 大大提高了程式員的創造力 不用再費很多心思去造輪子 更多的是分析需求 直接呼叫方法即可 畢竟語言和框架只是一種工具罷了 功能的實作才是最重要的
二 為什么需要封裝
封裝可以隱藏實作細節 方法 呼叫
因為不知道類里面是怎么實作的 我們只需要調動即可 做到了一定程度的封閉安全性
封裝可以對資料進行驗證 保證安全合理
比如 對名字進行初始化 規定名字字數不能超過六個字 我們可以在內部進行規定
三 怎么封裝
第一步將屬性進行私有化private
保證封裝安全性
第二步提供一個公共的set方法 用于對屬性判斷并賦值
對物件進行賦值
第三步提供一個公共的get方法用來獲取屬性的值
四 example
創建程式 在其中定義兩個類 Account和AccountTest類體會java的封裝性
1.Account類必須具有屬性 姓名(長度為2 3 4位) 余額(必須大于20) 密碼(必須是六位) 如果不滿足 則給出提示資訊 并給出默認值
2.通過setxx的方法給Account的屬性賦值
3.在AccountTest中測驗
public class Account {
public static void main(String[] args) {
AccountTest a = new AccountTest("wuyifan",15,"1234567");
System.out.println( a.toString());
}
}
class AccountTest{
String name;
double salary;
String password;
public AccountTest(String name, double salary,String password){
setName(name);
setSalary(salary);
setPassword(password);
}
public String getName() {
return name;
}
public void setName(String name) {
if(name.length()>=2&&name.length()<=4){
this.name = name;}
else{
System.out.println("wrong name");
this.name = "wu";
}
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
if(salary>20){
this.salary = salary;
}
else{
System.out.println("wrong salary");
this.salary=30;
}
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if(password.length()==6){
this.password = password;
}
else{
System.out.println("wrong password");
this.password ="123456";
}
}
@Override
public String toString() {
return "AccountTest{" +
"name='" + name + '\'' +
", salary=" + salary +
", password='" + password + '\'' +
'}';
}
}
五 細節
訪問修飾符 分為四大類 public 默認 protected private
對方法和屬性進行操作時 要遵循訪問修飾符的訪問范圍
六 總結
封裝是面向物件的基礎 大家只要知道封裝是將一個類的方法和屬性都封裝在一起就可以了 不用咬文嚼字
繼承
一 繼承是什么?
繼承是指 當多個類存在相同的屬性時 可以從這些類中抽象出父類 在父類中定義這些相同的屬性和方法 所有的子類不需要重新定義這些屬性和方法 只需要通過extends來宣告繼承父類即可
二 為什么要使用繼承?
我們撰寫了兩個類 一個小學生類 一個研究生類 兩個類的屬性和方法有很多是相同的 比如說 小學生有名字 初中生也有名字 小學生要學習 初中生也要學習 怎么辦 如果在兩個類中分別寫它們共有的方法和屬性 則重復代碼太多 過于冗余 所以我們可以使用一個父類 寫一遍 然后子類繼承只需要寫子類特有的方法和屬性即可 大大提高了代碼的復用性和整潔度
三 繼承的使用方法
class 子類 extends 父類{
//extends關鍵字
}
四 example
父類 Student.java
package com.shijiu.test;
public class Student {
//共有屬性
public String name;
public int age;
private double score;
//共有方法
public void setScore(double score) {
this.score = score;
}
public void showInfo(){
System.out.println("學生名"+name+"年齡"+age+"成績"+score);
}
}
子類 Pupil.java
package com.shijiu.test;
public class Pupil extends Student {
public void testing(){
System.out.println("小學生"+name+"正在考試");
}
}
子類 Graduate.java
package com.shijiu.test;
public class Graduate extends Student {
public void testing(){
System.out.println("大學生"+name+"正在考試");
}
}
五 繼承的注意事項
一 子類繼承了父類所有的屬性和方法 但是私有屬性不能在子類直接訪問 非私有屬性可以直接訪問 要通過(父類提供)公共的方法(get set 方法)去訪問
二 子類必須呼叫父類的構造器完成父類的初始化
三 當創建子類物件時 不管使用子類的哪個構造器 默認情況下總會去呼叫父類的無參構造器 如果父類沒有提供無參構造器 則必須在子類的構造器中用super去指定使用父類的哪個構造器完成對父類的初始化作業 否則編譯不會通過
四 如果希望指定去呼叫父類的某個構造器 則顯式的呼叫一下 super(引數串列)
五 super在使用的時候 必須放在構造器第一行
class A{
private String name;
public A(String name) {
this.name = name;
}
}
class B extends A{
public B(String name) {
super(name);
}
}
六 子類最多只能繼承一個父類(直接繼承) java是單繼承機制 但可以用介面實作多繼承
六 繼承的本質探究
public class Pupil extends Student {
public static void main(String[] args) {
Son son = new Son();
//一級一級向上查找
System.out.println(son.name);//大頭兒子
System.out.println(son.age);//39
System.out.println(son.hobby);//旅游
}
}
class GrandPa{
String name = "大頭爺爺";
String hobby = "旅游";
}
class Father extends GrandPa{
String name = "大頭爸爸";
int age = 39;
}
class Son extends Father{
String name = "大頭兒子";
}
本質上我們來看 繼承即是一種查找 從子類開始向上查找 直到Object類 查找它的屬性和方法
方法的多載和重寫
多載
方法多載(Overloading):在一個類中,如果兩個方法的方法名和相同,引數串列不同,那么這個方法就被定義為方法多載,
因此,只要在同一個類中,兩個方法的方法名相同,引數串列不同即可,與其權限修飾符、回傳值型別、方法無關,
class B extends A{
public B(String name) {
super(name);
}
public int m1(int a){
return a;
}
public int m1(int a,int b){
return a+b;
}
}
重寫
方法重寫:子類可以定義新的特征,當子類需要修改父類的一些方法進行擴展,增大功能,程式設計者常常把這樣的一種操作方法稱為重寫,也叫稱為覆寫或覆寫,
class A{
private String name;
public A(String name) {
this.name = name;
}
public int m1(int a){
return a;
}
}
class B extends A{
public B(String name) {
super(name);
}
@Override
public int m1(int a) {
return super.m1(a);
}
}
注意
重寫中 父類的引數串列和子類中的引數串列 和父類中的回傳型別和子類中的回傳型別必須一樣 否則不構成重寫 構成多載 并且子類的訪問修飾符范圍不能比父類的訪問修飾符范圍更小
多型
一 多型是什么?
方法或者物件具有多種狀態 是面向物件的第三大特征 多型是建立在封裝和繼承的基礎上的
對方法:方法的多載體現多型 很好理解 你輸入的引數不同 自然呼叫的方法不同
方法的重寫依然體現多型 不同的物件呼叫就會產生不同的效果
對物件:一個物件的編譯型別和運行型別可以不一樣 編譯型別在定義時 就確定了 不能再改變
運行型別可以改變 編譯型別看等號的左邊 運行型別看等號的右邊
Animal animal = new Dog();
//annimal 編譯型別是 Animal 運行型別是Dog
二 多型的兩種實作方式
前提:兩個物件(類)存在繼承關系
向上轉型
1.本質:父類的參考指向了子類的物件
2.語法:父型別別 參考名 = new 子型別別();
3.特點:編譯型別看左邊 運行型別看右邊
可以呼叫父類中的所有成員(需遵守訪問權限)
不能呼叫子類中特有成員
最終運行效果看子類的具體實作
編譯階段能呼叫哪些成員是由編譯型別來決定的
public class Pre {
public static void main(String[] args) {
At at = new Bt("jack");
at.m1();
}
}
class At{
private String name;
public At(String name) {
this.name = name;
}
public void m1(){
System.out.println("這是父類的方法");
}
}
class Bt extends At{
public Bt(String name) {
super(name);
}
@Override
public void m1() {
System.out.println("這是子類的方法");
}
}
當向上轉型之后,父類參考變數可以訪問子類中屬于父類的屬性和方法,但是不能訪問子類獨有的屬性和方法,
向下轉型
并不是所有的物件都可以向下轉型,只有當這個物件原本就是子類物件通過向上轉型得到的時候才能夠成功轉型,
At at = new Bt("jack");
Bt bt = (Bt) at;
bt.m1();
語法 子型別別 參考名 = (子型別別) 父類參考
只能強轉父類的參考 不能強轉 父類的物件
可以呼叫子型別別中所有的成員
三 多型的細節
屬性沒有重寫之說 屬性的值看編譯型別
Base base = new sub();
System.out.println(base.count);
看等號左邊 左邊的類中count是多少就是多少
instanceof比較運算子 判斷物件運行型別是否為類的子類或者是否為該類父類的型別
System.out.println(b instanceof A)
訪問屬性 看編譯型別 訪問方法 看運行型別
四 多型陣列
陣列的定義型別為父型別別 里面保存的實際元素型別為子型別別 可以依據不同的運行型別呼叫不同的方法
應用案例 現有一個繼承結構 要求創建一個Person物件 2個Student物件和2個Teacher物件 統一放在陣列中 并呼叫say方法
父類 人類
public class Person
{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String say(){
return name+'\t'+age;
}
}
子類學生類
package com.shijiu.poly;
public class Student extends Person {
private double score;
public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String say() {
return super.say()+"score"+score;
}
public void study(){
System.out.println("學生"+getName()+"正在學java");
}
}
子類教師類
package com.shijiu.poly;
public class Teacher extends Person {
private double salary;
public Teacher(String name, int age, double salary) {
super(name, age);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String say() {
return super.say()+'\t'+"salary"+salary;
}
public void teach(){
System.out.println("老師"+getName()+"正在上課");
}
}
主方法
package com.shijiu.poly;
public class PolyArray {
public static void main(String[] args) {
Person[] persons = new Person[5];
persons[0] = new Person("jack",20);
persons[1] = new Student("tom",20,89);
persons[2] = new Student("smith",20,60);
persons[3] = new Teacher("scott",30,20000);
persons[4] = new Teacher("servt",35,50000);
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i].say());
if(persons[i] instanceof Student){
((Student) persons[i]).study();
}
if(persons[i] instanceof Teacher){
//向下轉型
((Teacher) persons[i]).teach();
}
}
}
}
結語
大二了 也二十歲了 不是似懂非懂的少年了 也該為自己的未來做準備了 承擔一些自己應該擔當的責任了 不然呢 等到畢業找不到作業再努力嗎 回家靠爸媽養著?前幾天看到一個大佬拿了阿里的offer 對就是路飛學長 非常羨慕 看了他的文章 覺得這一路走來學長非常的努力和不容易 十分欽佩 每個人都是從小白過來的 他們可以我相信我也可以 希望我自己能夠見賢思齊 認真備戰 爭取能在畢業前交上屬于自己的滿意答卷 全力以赴 不留遺憾,
努力 為了自己想要的生活!
資料結構+java技術堆疊+力扣刷題
第一篇博客寫的不是特別好 見諒 以后會不斷進步的 求大佬們三連!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/304311.html
標籤:java
