目錄
代碼塊
a.區域代碼塊:
b.構造代碼塊:
c.靜態代碼塊
繼承
繼承概述
繼承案列
繼承的好處
Java中繼承的特點
Java中繼承的注意事項
繼承中成員變數的關系
super關鍵字
繼承中構造方法的關系
繼承中成員方法的關系
方法重寫概述
final關鍵字
代碼塊
在Java中,使用{}括起來的代碼被稱為代碼塊,根據其位置和宣告的不同,可以分為區域代碼塊,構造代碼塊,靜態代碼塊,同步代碼塊(到多執行緒再說),
a.區域代碼塊:
在方法中出現;限定變數生命周期,及早釋放,提高記憶體利用率,
在同一個類的同一個方法中,如果存在多個區域代碼塊,執行順序是自上而下的
public class Test1 {
public static void main(String[] args) {
//第一個代碼塊
{
int a=100;
System.out.println(a);
}
//第二個代碼塊
{
int b =200;
System.out.println(b);
}
//第三個代碼塊
{
int c=300;
System.out.println(c);
}
}
}

b.構造代碼塊:
在類中方法外出現;多個構造方法方法中相同的代碼存放到一起,每次呼叫構造都執行,并且在構造方法前執行,
class Demo{
//創建一個無參構造方法
Demo(){
int a=10;
System.out.println(a);
}
//創建一個構造代碼塊(定義在類中方法外,用大括號括起來的代碼,稱為構造代碼塊)
{
int b=20;
System.out.println(b);
}
}
public class Test2 {
public static void main(String[] args) {
//創建Demo的物件
Demo demo = new Demo();
//創建一個區域代碼塊
{
int c=30;
System.out.println(c);
}
}
}

可以看出當一個類中既存在構造方法又存在構造代碼塊,在創建物件時,會先執行構造代碼塊,再執行構造方法,而main方法里還是自上而下執行,
c.靜態代碼塊
在類中方法外出現,并加上static修飾;用于給類進行初始化,在加載的時候就執行,并且值執行一次,
class Demo{
//創建一個無參構造方法
Demo(){
int a=10;
System.out.println(a);
}
//創建一個構造代碼塊(定義在類中方法外,用大括號括起來的代碼,稱為構造代碼塊)
{
int b=20;
System.out.println(b);
}
//創建一個靜態代碼塊
static {
int d=40;
System.out.println(d);
}
}
public class Test2 {
public static void main(String[] args) {
//創建Demo的物件
Demo demo = new Demo();
//創建一個區域代碼塊
{
int c=30;
System.out.println(c);
}
}
}

靜態代碼塊優先其他代碼塊執行,不創建物件也會執行,
最后我們整合一下:
class Demo3{
Demo3(){
System.out.println("Demo3的無參構造方法");
}
static {
System.out.println("Demo3中的靜態代碼塊");
}
{
System.out.println("Demo3中的構造代碼塊");
}
}
public class Test3 {
static {
System.out.println("Test3中的靜態代碼塊");
}
public static void main(String[] args) {
{
System.out.println("main方法中的區域代碼塊");
}
Demo3 demo3 = new Demo3(); //創建Demo3的物件
}
}
Demo3類需要創建物件才能訪問,所以先走Test3類,Test3中靜態代碼塊優先,再執行main方法里面的,直到創建了Demo3的物件,開始按靜態代碼塊——構造代碼塊——構造方法的順序執行,

繼承
繼承概述
a.多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那么多個類無需再定義這些屬性和行為,只要繼承那個類即可,
b.通過extends關鍵字可以實作類與類的繼承
格式: class 子類名 extends 父類名 {}
c.單獨的這個類稱為父類,基類或者超類;這多個類可以稱為子類或者派生類, 有了繼承以后,我們定義一個類的時候,可以在一個已經存在的類的基礎上,還可以定義自己的新成員,
繼承案列
class Father{
//創建父類,定義成員變數
String name;
int age;
public void sleep(){ //定義一個方法
System.out.println("睡覺");
}
}
class Son{
//創建一個子類,定義成員變數
String name;
int age;
public void sleep(){
System.out.println("睡覺");
}
}
當我們創建了兩個或更多有共同之處的類的時候,發現這樣就很麻煩,如上父與子類都有相同的成員變數,都有一個共同的方法,所以我們能利用繼承來改進,
改進后:
class Person{ //定義一個人類,提取出父與子的相同處
String name;
int age;
public void sleep(){
System.out.println("睡覺");
}
}
class Father extends Person{ //創建父類繼承人類
}
class Son extends Father{ //創建子類繼承父類
public void play(){ //創建一個子類特有的方法
System.out.println("玩游戲");
}
}
public class Extends1 {
public static void main(String[] args) {
//創建父類物件
Father father = new Father();
father.sleep(); //父類通過繼承能訪問Person類的方法
//創建子類物件
Son son = new Son();
son.sleep(); //子類通過繼承能訪問Person類的方法
son.play(); //子類也可以訪問自身特有的方法
}
}

使用繼承后,父與子類都能訪問Person類的方法,而且子類也能訪問自己特有的方法,
繼承的好處
a.提高了代碼的復用性
多個類相同的成員可以放到同一個類中
b.提高了代碼的維護性
如果功能的代碼需要修改,修改一處即可
c.讓類與類之間產生了關系,是多型的前提
其實這也是繼承的一個弊端:類的耦合性很強
Java中繼承的特點
a.Java只支持單繼承,不支持多繼承,
一個類只能有一個父類,不可以有多個父類,
class SubDemo extends Demo{} (正確)
class SubDemo extends Demo1,Demo2... (錯誤)
b.Java支持多層繼承(繼承體系)
class A{}
class B extends A{}
class C extends B{}
Java中繼承的注意事項
a.子類只能繼承父類所有非私有的成員(成員方法和成員變數)
其實這也體現了繼承的另一個弊端:打破了封裝性
b.子類不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類構造方法,
c.想要初始化子類,必須先初始化父類
d.不要為了部分功能而去繼承
繼承中成員變數的關系
案例:
class Father2 { //創建父類
int a = 40;
int b =50;
public void num2() {
System.out.println(a);
}
}
class Son2 extends Father2 { //子類繼承父類
int a = 20;
public void num1() {
System.out.println(a);
}
public void num3(){
System.out.println(b);
}
}
public class Extends2 {
public static void main(String[] args) {
//創建子類物件
Son2 son2 = new Son2();
son2.num1(); //就近原則,輸出的應該是Son2中的a
son2.num2(); //子類中沒有該方法,到父類中尋找
son2.num3(); //子類中沒有元素b,去父類尋找
}
}

結論:
在子類方法中訪問一個變數
a.首先在子類區域范圍找
b.然后在子類成員范圍找
b.最后在父類成員范圍找(肯定不能訪問到父類區域范圍)
d.如果還是沒有就報錯,(不考慮父親的父親…)
super關鍵字
class Father3{
int num=30;
}
class Son3 extends Father3{
int num =40;
public void show(){
int num=50;
System.out.println(num); //可以訪問到show方法里面的num
System.out.println(this.num); //使用在封裝里說的this關鍵字可以訪問到類中的num
}
}
public class Extends3 {
public static void main(String[] args) {
Son3 son3 = new Son3();
son3.show();
}
}
如上,我們可以訪問到子類方法里面的num,也可以利用this關鍵字訪問子類中方法外的num,那如果我們想訪問父類中的num呢,Java里提供了一個關鍵字:super
(在上面代碼子類show方法里加入 System.out.println(super.num);就可以訪問父類里面的num)

super的用法和this區別
this代表本類對應的參考,
super代表父類存盤空間的標識(可以理解為父類參考)
用法(this和super均可如下使用)
a.訪問成員變數:
this.成員變數
super.成員變數
b.訪問構造方法
this(…)
super(…)
c.訪問成員方法
this.成員方法()
super.成員方法()
繼承中構造方法的關系
子類中所有的構造方法默認都會訪問父類中空引數的構造方法,
因為子類會繼承父類中的資料,可能還會使用父類的資料,所以,子類初始化之前,一定要先完成父類資料的初始化, 每一個構造方法的第一條陳述句默認都是:super()
例:
class Father4{
Father4(){
System.out.println("這是父類中的無參構造方法");
}
Father4(String s){
System.out.println("這是父類中的有參構造方法"+s);
}
}
class Son4 extends Father4{
Son4(){
System.out.println("這是子類中的無參構造方法");
}
Son4(String s){
System.out.println("這是子類的有參構造方法"+s);
}
}
public class Extends4 {
public static void main(String[] args) {
//創建子類物件
Son4 son4 = new Son4("User");
}
}

當父類中沒有無參構造方法:
a.子類通過super去顯示呼叫父類其他的帶參的構造方法
例:
class Father4{
Father4(String s){
System.out.println("這是父類中的有參構造方法"+s);
}
}
class Son4 extends Father4{
Son4(){
super("FU");
System.out.println("這是子類中的無參構造方法");
}
Son4(String s){
super("FU");
System.out.println("這是子類的有參構造方法"+s);
}
}
public class Extends4 {
public static void main(String[] args) {
//創建子類物件
Son4 son4 = new Son4("User");
}
}

b.子類通過this去呼叫本類的其他構造方法
本類其他構造也必須首先訪問了父類構造
例:
class Father4{
Father4(String s){
System.out.println("這是父類中的有參構造方法"+s);
}
}
class Son4 extends Father4{
Son4(){
super("FU");
System.out.println("這是子類中的無參構造方法");
}
Son4(String s){
this(); //使用this關鍵字,先呼叫子類的無參構造方法 ,間接的呼叫父類構造方法
System.out.println("這是子類的有參構造方法"+s);
}
}
public class Extends4 {
public static void main(String[] args) {
//創建子類物件
Son4 son4 = new Son4("User");
}
}

c.一定要注意: super(…)或者this(….)必須出現在第一條陳述句上, 否則,就會有父類資料的多次初始化
繼承中成員方法的關系
子父類中同名和不同名的成員方法
class Father5{
public void show(){
System.out.println("父類中的show方法");
}
public void show3(){
System.out.println("父類中的show3方法");
}
}
class Son5 extends Father5{
public void show(){
System.out.println("子類中的show方法");
}
public void show2(){
System.out.println("子類中的show2方法");
}
}
public class Extends5 {
public static void main(String[] args) {
Son5 son5 = new Son5();
son5.show(); //呼叫子類的show方法,就近原則
son5.show2(); //呼叫子類的show2方法
son5.show3(); //子類訪問show3方法,子類沒有去父類中找
}
}

結論: 通過子類物件去訪問一個方法,首先在子類中找,然后在父類中找,如果還是沒有就報錯,
方法重寫概述
子類中出現了和父類中一模一樣的方法宣告,也被稱為方法覆寫,方法復寫,
使用特點:
如果方法名不同,就呼叫對應的方法
如果方法名相同,最終使用的是子類自己的
方法重寫的應用:
當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容,
例:
class Father6{
public void study(String s){
System.out.println("學習"+s);
}
}
class Son6 extends Father6{
public void study(String s){ //重寫父類中的study方法
System.out.println("學習"+s+"中的繼承");
}
public void study2(String s){
System.out.println("學習"+s); //子類特有的方法
}
}
public class Extends6 {
public static void main(String[] args) {
//創建子類物件
Son6 son6 = new Son6();
son6.study("java"); //呼叫子類的study方法
son6.study2("大資料");
}
}

方法重寫的注意事項
a.父類中私有方法不能被重寫
b.子類重寫父類方法時,訪問權限不能更低
c.父類靜態方法,子類不能進行重寫
方法重寫與方法多載的區別
方法重寫(override)是發生在繼承關系中子類里的,方法多載(overload)是發生在同一個類中的
多載是方法名一樣,引數串列不一樣
重寫是方法名,引數串列,回傳值都一樣,實作不一樣,叫方法的重寫,
final關鍵字
final關鍵字是最終的意思,可以修飾類,成員變數,成員方法,
特點:
a.修飾方法,方法不能被重寫
例:當我們不想讓子類覆寫重寫父類中的方法或者功能,只能讓子類去使用時,可以使用final
class Father7{
public final void show(){ //使用final修飾方法
System.out.println("父類中的show方法");
}
}
class Son7 extends Father7{
@Override
public void show(){ //子類不能重寫,否則報錯
System.out.println("這是子類中的show方法");
}
}
public class Extends7 {
public static void main(String[] args) {
Son7 son7 = new Son7();
son7.show();
}
}

可以看到子類如果重寫了父類用final修飾的方法,運行就會報錯,
b.修飾類,類不能被繼承

c.修飾變數,變數就變成了常量,只能被賦值一次(在構造方法完畢之前賦值即可)

final修飾區域變數
a. 在方法內部,該變數不可以被改變
b. 在方法宣告上,基本型別和參考型別作為引數的情況
基本型別,是值不能被改變
參考型別,是地址值不能被改變(該物件堆記憶體中的值是可以改變的)
c.final修飾變數的初始化時機
在物件構造完畢前即可
面向物件三大特征——封裝
https://blog.csdn.net/qq_52400447/article/details/122520149
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/415128.html
標籤:其他
上一篇:微服務架構 | 3.4 HashiCorp Consul 注冊中心
下一篇:快遞鳥介面國內常用快遞公司編碼表
