繼承
1袍睡、定義
在Java中定義一個(gè)類時(shí),讓該類通過(guò) extends 關(guān)鍵字繼承一個(gè)已經(jīng)存在的類肋僧,同時(shí)能夠?qū)⒈焕^承的父類中設(shè)定好的屬性和方法直接拿過(guò)來(lái)使用斑胜,這就是類的繼承。
(1)被繼承的類叫做父類(基類)嫌吠,新的類叫做子類(派生類)止潘。
(2)子類可以繼承父類的所有屬性和方法,同時(shí)也可以增加屬于自己的屬性和方法辫诅。
(3)在繼承時(shí)凭戴,子類不能夠繼承父類的構(gòu)造方法,也不能繼承父類的私有屬性和私有方法炕矮。
2么夫、語(yǔ)法格式
[ 修飾符 ] class 子類名 extends 父類名 { }
//父類
public class Father {
String name;
int age;
public Father(String name,int age){
super();
this.name = name;
this.age = age;
}
public Father(){
System.out.println("new Father...");
}
public void eat(){
System.out.println(this.name+"正在吃東西");
}
public void sleep(){
System.out.println(this.name+"正在睡覺(jué)");
}
}
//子類
public class Son extends Father{
public Son(){
System.out.println("new Son...");
}
public void eat(){
System.out.println(t"正在吃東西");
}
public void sleep(){
System.out.println("正在睡覺(jué)");
}
}
3、規(guī)則和優(yōu)點(diǎn)
(1)Java中只支持單繼承肤视,也就是說(shuō)每個(gè)子類只能有一個(gè)父類档痪,不能有多繼承。
(2)一個(gè)父類可以有多個(gè)子類邢滑。
(3)子類繼承父類的所有屬性和方法腐螟,同時(shí)也可以增加屬于自己的屬性和方法。
(4)不能繼承 private 修飾的屬性和方法殊鞭。
(5) 在Java中任何的class都有一個(gè)父類 Object 類。
——Object類是所有class的父類尼桶。
——Java中只允許單繼承操灿。
——若手動(dòng)添加指定父類,則系統(tǒng)不會(huì)默認(rèn)Object為該class的父類泵督。
——若沒(méi)有繼承任何父類趾盐,則系統(tǒng)默認(rèn)Object為其父類。
(6) 優(yōu)點(diǎn):使編碼更高效,可以代碼重用救鲤。
4久窟、子類實(shí)例化的過(guò)程
(1)子類實(shí)例化時(shí)要先實(shí)例化它的父類,然后在實(shí)例化子類本缠。
(2)要先調(diào)用父類的構(gòu)造方法斥扛,父類的構(gòu)造方法運(yùn)行完畢后,才能調(diào)用子類的構(gòu)造方法丹锹。
(3)子類的構(gòu)造器——子類不能夠繼承父類的構(gòu)造器稀颁;
——在子類中創(chuàng)建構(gòu)造器時(shí),必須調(diào)用父類的構(gòu)造器楣黍;
——子類可以在自己的構(gòu)造器中使用 super 關(guān)鍵字來(lái)調(diào)用父類的構(gòu)造器匾灶;
—— 如果使用super關(guān)鍵字調(diào)用父類的構(gòu)造器,必須寫在子類構(gòu)造器的第一行租漂;
—— 如果調(diào)用的是父類的無(wú)參構(gòu)造器阶女,可以不用寫super();
—— 如果子類調(diào)用了父類的無(wú)參構(gòu)造器哩治,而父類中沒(méi)有無(wú)參構(gòu)造器秃踩,則編譯器提示錯(cuò)誤。
super(參數(shù)1锚扎,參數(shù)2吞瞪,...);
5、super 和 this 關(guān)鍵字
(1)super()
—— 作用:調(diào)用父類的構(gòu)造器驾孔;
—— 只能出現(xiàn)在子類的構(gòu)造器中芍秆,且必須是放在第一行;
—— super()中的參數(shù)翠勉,決定了要調(diào)用父類的哪個(gè)構(gòu)造器妖啥;
—— 如果子類構(gòu)造器中沒(méi)有出現(xiàn) super ,那么編譯器會(huì)默認(rèn)加上super()对碌,即調(diào)用父類的空構(gòu)造器荆虱,如果父類沒(méi)有空構(gòu)造器,編譯器提示錯(cuò)誤朽们。
(2)this()
—— 作用:調(diào)用本類的構(gòu)造器怀读;
—— 只能寫在構(gòu)造器的第一行;
(3)在同一個(gè)構(gòu)造器中 super()和 this()不能同時(shí)出現(xiàn)骑脱。
(4)super:指向父類的引用菜枷;this:指向本類的引用。
//父類
public abstract class Shape {
private double area;
private double per;
private String color;
public void setArea(double area) {
this.area = area;
}
public void setPer(double per) {
this.per = per;
}
public void setColor(String color) {
this.color = color;
}
public Shape() {
super();
}
public Shape(String color){
super();
this.color = color;
}
public String getColor(){
return color;
}
public abstract double getArea();
public abstract double getPer();
public abstract void showAll();
}
//子類
public class Rectangle extends Shape{
private int width;
private int height;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Rectangle() {
super();
}
public Rectangle(int width, int height,String color) {
super(color); //調(diào)用父類的有參構(gòu)造方法
this.width = width;
this.height = height;
}
@Override
public double getArea() {
double area = width*height;
return area;
}
@Override
public double getPer() {
double per = (width+height)*2;
return per;
}
@Override
public void showAll() {
System.out.println("Rectangle的長(zhǎng)度是:"+width);
System.out.println("Rectangle的寬度是:"+height);
System.out.println("Rectangle的面積是:"+getArea());
System.out.println("Rectangle的周長(zhǎng)是:"+getPer());
System.out.println("Rectangle的顏色是:"+getColor());
}
}
//測(cè)試類
public class Test {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(4,5,"black");
rectangle.showAll();
}
}
訪問(wèn)權(quán)限修飾符
1叁丧、封裝
封裝就是把客觀事物封裝成抽象的類啤誊,把對(duì)象的屬性和行為結(jié)合在一個(gè)獨(dú)立的類中岳瞭,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏蚊锹。
隱藏屬性瞳筏、方法或?qū)崿F(xiàn)細(xì)節(jié)的過(guò)程稱為封裝。
<1>封裝可以隱藏實(shí)現(xiàn)細(xì)節(jié)牡昆,使得代碼模塊化姚炕。
<2>讓使用者只能通過(guò)事先制定好的方法來(lái)訪問(wèn)數(shù)據(jù),可以方便地加入控制邏輯迁杨,限制對(duì)屬性的不合理操作钻心。
<3>便于修改,增強(qiáng)代碼的可維護(hù)性铅协。
<4>封裝的目的是實(shí)現(xiàn)代碼重用捷沸。
2、訪問(wèn)權(quán)限修飾符
Java有四個(gè)作用域狐史,訪問(wèn)權(quán)限修飾符 ----- 適用于類和屬性
(1)public(公有)-----任何位置都可以訪問(wèn)
(2)protected(受保護(hù)的)-----在同一個(gè)包中的所有類都可以訪問(wèn)痒给,以及該類的子類(可以是不同包)
(3)default(默認(rèn)的)-----在同一個(gè)包中
(4)private(私有的)-----只能在本類中
用來(lái)控制類的成員和類的使用范圍。
——類成員的訪問(wèn)權(quán)限修飾符:public骏全、protected苍柏、default、private
——類的訪問(wèn)權(quán)限修飾符:public姜贡、default
方法的覆蓋(重寫) —— override
方法的覆蓋试吁、重寫:子類對(duì)從父類繼承過(guò)來(lái)的方法進(jìn)行改造,重新編寫楼咳。
——在子類繼承父類時(shí)發(fā)生熄捍。
1、規(guī)則
在子類中的覆蓋(重寫)方法和父類中被覆蓋(重寫)的方法應(yīng)具有:
<1>相同的方法名
<2>相同的參數(shù)列表(參數(shù)數(shù)量母怜、參數(shù)類型余耽、參數(shù)順序都要相同)
<3>相同的返回值類型
<4>子類覆蓋(重寫)方法的訪問(wèn)權(quán)限要不小于(大于等于)父類中被覆蓋(重寫)方法的訪問(wèn)權(quán)限。
//父類
public class Father {
String name;
public void eat(){
System.out.println("正在吃東西");
}
protected String run(){
return "跑步";
}
}
//子類
public class Son extends Father{
String name;
//方法重寫苹熏,返回值類型必須相同
// public int eat(){
// System.out.println("吃東西");
// return 0;
// }
//方法重寫碟贾,子類的訪問(wèn)權(quán)限要不小于(大于等于)父類的訪問(wèn)權(quán)限
public String run(){
return "跑步";
}
}
方法的覆蓋(重寫)(override) 和方法重載(overload)的區(qū)別
方法的覆蓋、重寫 | 方法重載 |
---|---|
重寫發(fā)生在兩個(gè)有繼承關(guān)系的class中 | 重載發(fā)生在一個(gè)class中 |
重寫中方法名和參數(shù)列表必須完全相同 | 重載中方法名相同轨域,但參數(shù)列表不同 |
方法重寫袱耽,返回值類型必須相同 | 方法重載,與返回值類型無(wú)關(guān) |
子類覆蓋(重寫)方法的訪問(wèn)權(quán)限要不小于(大于等于)父類中被覆蓋(重寫)方法的訪問(wèn)權(quán)限干发。 | 方法重載朱巨,可以有不同的訪問(wèn)修飾符 |
引用數(shù)據(jù)類型的轉(zhuǎn)換
1、向上轉(zhuǎn)換(Upcasting)——子類轉(zhuǎn)換成父類铐然,自動(dòng)轉(zhuǎn)換蔬崩;
——前提是:具有繼承或?qū)崿F(xiàn)關(guān)系;
——向上轉(zhuǎn)換損失了子類新擴(kuò)展的屬性和方法搀暑,只可以使用從父類中繼承的屬性和方法沥阳。
2、向下轉(zhuǎn)換(Downcasting):強(qiáng)制轉(zhuǎn)換
——將父類對(duì)象顯示的轉(zhuǎn)換成子類類型自点;
//在創(chuàng)建出這個(gè)對(duì)象(引用)時(shí)桐罕,該對(duì)象的類型是子類
PrintMechine print1 = new HeibaiPrint();
print1.print();
//非基本數(shù)據(jù)類型,大轉(zhuǎn)小桂敛,也強(qiáng)轉(zhuǎn)
//在創(chuàng)建出這個(gè)對(duì)象時(shí)功炮,該對(duì)象的類型是子類
//例如:print1 在實(shí)例化時(shí)是new HeibaiPrint()
HeibaiPrint heibaiPrint = (HeibaiPrint)print1;
heibaiPrint.print();
//創(chuàng)建父類,然后直接將父類轉(zhuǎn)換成子類是不可行的
instanceof運(yùn)算符
1术唬、 判斷某個(gè)變量的數(shù)據(jù)類型(小范圍)是否符合某個(gè)大范圍的數(shù)據(jù)類型
——變量 instanceof 數(shù)據(jù)類型
2薪伏、判斷某個(gè)對(duì)象(引用)是否屬于某個(gè)類的一個(gè)實(shí)例。
——對(duì)象 instanceof 類
3粗仓、它的返回值數(shù)據(jù)類型是 boolean 型嫁怀。
public class PrintMechine {
public void print(){ }
}
public class CaisePrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是彩色的");
}
}
public class HeibaiPrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是黑白色的");
}
}
public class SanDPrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是3D的");
}
}
public class Test01 {
public static void main(String[] args) {
//instanceof:判斷某個(gè)對(duì)象或引用是否屬于某個(gè)類
// 判斷某個(gè)變量的數(shù)據(jù)類型(小范圍)是否符合某個(gè)大范圍的數(shù)據(jù)類型
//父類的引用 print1 的類型是父類類型
PrintMechine print1 = new PrintMechine();
//父類的引用 print2 的類型是子類類型
PrintMechine print2 = new HeibaiPrint();
//print2 變量能夠轉(zhuǎn)換成 HeibaiPrint 類型嗎
if (print2 instanceof HeibaiPrint) {
HeibaiPrint heibaiPrint2 = (HeibaiPrint) print2;
heibaiPrint2.print();
}
if (print1 instanceof HeibaiPrint) { //false:不運(yùn)行方法體
//(HeibaiPrint) print1:將父類類型強(qiáng)制轉(zhuǎn)換成子類類型
HeibaiPrint heibaiPrint3 = (HeibaiPrint) print1;
heibaiPrint3.print();
}
//java.lang.ClassCastException :類型轉(zhuǎn)換異常
}
}
多態(tài) --- Polymorphism
多態(tài):多形性,父類型引用指向子類型的實(shí)現(xiàn)借浊,動(dòng)態(tài)改變行為塘淑。一個(gè)class,隨著不同的場(chǎng)景蚂斤,它的表現(xiàn)形態(tài)存捺,會(huì)隨之發(fā)生變化。
多態(tài)是具有表現(xiàn)多種形態(tài)的能力的特征曙蒸。
同一個(gè)實(shí)現(xiàn)接口捌治,使用不同的實(shí)例而使用執(zhí)行不同的操作。
(1)多態(tài)的實(shí)現(xiàn)條件:
<1>父類的引用逸爵,引用派生類(子類)的實(shí)例:
<2>父類的引用具滴,調(diào)用重寫后的方法
<3>在運(yùn)行調(diào)用時(shí)形成多態(tài)
<4>條件:(1)繼承 (2)方法重寫 (3)類型轉(zhuǎn)換
(2)多態(tài)的目的是實(shí)現(xiàn)接口重用
(3)多態(tài)的作用,就是為了類在繼承和派生的時(shí)候师倔,保證使用“家譜”中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用构韵。
(4)多態(tài)的優(yōu)點(diǎn):
—— 簡(jiǎn)化代碼;
—— 改善代碼的組織性和可讀性趋艘;
—— 易于擴(kuò)散
public class PrintMechine {
public void print(){ }
}
public class CaisePrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是彩色的");
}
}
public class HeibaiPrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是黑白色的");
}
}
public class SanDPrint extends PrintMechine{
@Override
public void print() {
System.out.println("打印出的紙張是3D的");
}
}
public class Test {
public static void main(String[] args) {
//多態(tài)
//父類的引用疲恢,引用子類的實(shí)例
//父類的引用,調(diào)用子類重寫后的方法
//在運(yùn)行調(diào)用的同時(shí)形成多態(tài)
//條件:(1)繼承 (2)方法重寫 (3)類型轉(zhuǎn)換
//在創(chuàng)建出這個(gè)對(duì)象(引用)時(shí)瓷胧,該對(duì)象的類型是子類
PrintMechine print1 = new HeibaiPrint();
print1.print();
PrintMechine print2 = new CaisePrint();
print2.print();
PrintMechine print3 = new SanDPrint();
print3.print();
//非基本數(shù)據(jù)類型显拳,大轉(zhuǎn)小,也強(qiáng)轉(zhuǎn)
//在創(chuàng)建出這個(gè)對(duì)象時(shí)搓萧,該對(duì)象的類型是子類
//例如:print1 在實(shí)例化時(shí)是new HeibaiPrint()
HeibaiPrint heibaiPrint = (HeibaiPrint)print1;
heibaiPrint.print();
//創(chuàng)建父類杂数,然后直接將父類轉(zhuǎn)換成子類是不可行的
}
}
//創(chuàng)建一個(gè)調(diào)用方法 父類 引用名
public static void print(ObjectDemo demo){
//父類的引用調(diào)用重寫后的方法
//父類的引用.重寫后的方法()
if (demo.getAge() > 20) {
System.out.println("老張的大兒子叫:" + demo.getName() + " 今年" + demo.getAge() );
}
if (demo.getName().equals("zhangyusheng")){
System.out.println("老張的二兒子叫:" + demo.getName() + " 今年" + demo.getAge());
}
}
//運(yùn)行調(diào)用方法
public static void main(String[] args){
//父類的引用宛畦,引用派生類(子類)的實(shí)例:父類 引用 = new 子類();
ObjectDemo demo = new SonDemoA();
//父類的引用調(diào)用重寫后的方法:引用.重寫后的方法(); 例如:demo.getName();
System.out.println(demo.getName());
System.out.println(demo.getAge());
System.out.println("==================================");
//在運(yùn)行調(diào)用時(shí)形成多態(tài)
print(new SonDemoA());
System.out.println("==================================");
print(new SonDemoB());
System.out.println("==================================");
}
}
//父類
class ObjectDemo{
public int getAge(){
return 50;
}
public String getName(){
return "zhangsan";
}
}
//子類繼承父類,重寫父類的方法
class SonDemoA extends ObjectDemo{
//override:方法重寫
public int getAge(){
return 25;
}
public String getName(){
return "zhangxueyou";
}
}
class SonDemoB extends ObjectDemo{
public int getAge(){
return 18;
}
public String getName(){
return "zhangyusheng";
}
}
抽象類 —— abstract class
abstract:抽象
abstract class:抽象類:有抽象方法的類就是抽象類揍移。
1次和、語(yǔ)法格式
[ 訪問(wèn)權(quán)限修飾符 ] abstract class 類名 { ... }
2、抽象方法
抽象方法:只有方法聲明那伐,沒(méi)有方法實(shí)現(xiàn)(方法體)的方法踏施。
[ 訪問(wèn)權(quán)限修飾符 ] abstract 返回值類型 抽象方法名(參數(shù)列表);
//abstract class :抽象類
public abstract class Animal {//抽象類:有抽象方法的類就是抽象類罕邀。抽象類中也可以有普通方法
String name;
//構(gòu)造方法
public Animal(String name){
this.name = name;
}
//非抽象方法
public void sleep(){
System.out.println("睡覺(jué)");
}
//抽象方法
//abstract僅僅是對(duì)方法的一個(gè)聲明畅形,并沒(méi)有具體實(shí)現(xiàn)
public abstract void eat();
public abstract void play();
}
3、規(guī)則
(1)抽象類不能夠被實(shí)例化 ———— instantiate:實(shí)例化诉探,示例
(2)抽象類中有構(gòu)造方法日熬。
(3)抽象類中也可以有普通方法。
(4)抽象類中的抽象方法必須在它的子類中被實(shí)現(xiàn)肾胯,否則該子類只能聲明為 abstract 碍遍。
(5)抽象方法必須被子類覆蓋(重寫),抽象方法不能夠?yàn)?private阳液。
(6)不能夠?qū)?gòu)造方法怕敬、類成員方法聲明為抽象方法。
(7)abstract 抽象方法不能夠和 static 同用帘皿。
4东跪、使用抽象類的情況
(1)當(dāng)一個(gè)類的一個(gè)或多個(gè)方法是抽象方法時(shí);
(2)當(dāng)一個(gè)類是抽象類的子類鹰溜,并且沒(méi)有實(shí)現(xiàn)父類的所有抽象方法時(shí)虽填,即只實(shí)現(xiàn)了部分;
(3)當(dāng)一個(gè)類實(shí)現(xiàn)接口曹动,并且不能夠?yàn)樗谐橄蠓椒ǘ继峁?shí)現(xiàn)時(shí)斋日;
final 關(guān)鍵字
final 關(guān)鍵字可以修飾的元素
1、類:final 修飾的類不能夠被繼承墓陈;
2恶守、變量:final 修飾的變量不能夠被重新賦值;
——在聲明時(shí)直接賦值贡必,或者在構(gòu)造器中賦值兔港。
——系統(tǒng)不會(huì)對(duì)final 屬性默認(rèn)的賦初始值。
3仔拟、方法:final 修飾的方法不能夠在子類中被覆蓋(重寫)衫樊,即不能夠進(jìn)行修改。并且不能夠被子類繼承。
接口 —— interface
1科侈、接口的聲明
——是方法的定義和常量值的集合载佳。
——關(guān)鍵字:implements:實(shí)現(xiàn) 。
——接口中只有常量和抽象方法臀栈,沒(méi)有變量和方法的實(shí)現(xiàn)刚盈。
[ 訪問(wèn)權(quán)限修飾符 ] interface 接口名 { 接口的成員 }
——接口成員:常量、抽象方法
——接口可以多實(shí)現(xiàn)挂脑。
public interface InterfaceDemo {
//在接口中不能夠聲明變量,也不能夠定義普通方法
// int a;
// int b;
// public void a(){ }
// public void b(){ }
// 在接口中不能夠聲明變量欲侮,也不能夠定義普通方法
// 接口中定義的屬性必須是 public static final (常量)
// 接口中定義的方法必須是 public abstract
// 接口中屬性必須都是常量崭闲。
// 接口中方法必須都是抽象方法。
int a = 0; //接口中屬性默認(rèn)為public static final
public static final int b = 100;
public abstract void a();
public abstract void b();
}
2威蕉、注意
(1)接口不是一個(gè)類刁俭,沒(méi)有構(gòu)造器,不能夠被實(shí)例化韧涨。
(2)接口使用 interface 關(guān)鍵字來(lái)定義牍戚,而不是class。
(3)接口中定義的屬性必須是 public static final —— 常量
(4)接口中定義的方法必須是 public abstract —— 抽象方法
(5)在接口中不能夠聲明變量虑粥,也不能夠定義普通方法 如孝。
(6)子類可以實(shí)現(xiàn)多個(gè)接口,在接口之間用“娩贷,”分隔寫多個(gè)接口名第晰。
(7)如果不想實(shí)現(xiàn)接口,在實(shí)現(xiàn)類中加 abstract 修飾符將類抽象化彬祖。
//接口1
public interface Temp {
public static final int a = 0;
public static final int b = 100;
public abstract void a();
public abstract void b();
}
//接口2
public interface Temp2 {
public static final int x = 10;
public static final int y = 20;
public abstract void x();
public abstract void y();
}
//接口的實(shí)現(xiàn)類 Impl
public class TempImpl implements Temp,Temp2{
@Override
public void a() {
System.out.println("A");
}
@Override
public void b() {
System.out.println("B");
}
@Override
public void x() {
System.out.println("X");
}
@Override
public void y() {
System.out.println("Y");
}
}
//接口的測(cè)試類
public class TempTest {
public static void main(String[] args) {
TempImpl tempImpl = new TempImpl();
tempImpl.a();
tempImpl.b();
System.out.println(tempImpl.a);
System.out.println(tempImpl.b);
tempImpl.x();
tempImpl.y();
System.out.println(tempImpl.x);
System.out.println(tempImpl.y);
}
}
3茁瘦、接口的意義
(1)接口可以實(shí)現(xiàn)方法的定義和方法的實(shí)現(xiàn)相分離,降低模塊間或系統(tǒng)間的耦合性储笑。
(2)接口可以實(shí)現(xiàn)多繼承甜熔。
4、接口和類的關(guān)系
——類實(shí)現(xiàn)接口:關(guān)鍵字:implements:實(shí)現(xiàn) 突倍。
(1)若想要實(shí)現(xiàn)一個(gè)接口腔稀,必須要編寫實(shí)現(xiàn)接口的類 Impl 。
(2)如果一個(gè)類想要實(shí)現(xiàn)一個(gè)接口羽历,那么這個(gè)類就必須實(shí)現(xiàn)這個(gè)接口中所有的抽象方法烧颖。否則這個(gè)類只能聲明為抽象類。
(3)多個(gè)無(wú)關(guān)的類可以實(shí)現(xiàn)一個(gè)接口窄陡,一個(gè)類可以實(shí)現(xiàn)多個(gè)無(wú)關(guān)的接口炕淮。
(4)一個(gè)類可以在繼承一個(gè)父類的同時(shí),實(shí)現(xiàn)一個(gè)或多個(gè)接口跳夭。
接口和抽象類的區(qū)別
接口 | 抽象類 |
---|---|
接口是一個(gè)接口 - interface | 抽象類是一個(gè)類 - class |
接口可以多實(shí)現(xiàn) | 抽象類只能是單繼承 |
接口中必須全部都是抽象方法 | 抽象類中可以有非抽象方法涂圆,包括抽象方法们镜,構(gòu)造方法,普通方法 |
接口中定義的抽象方法必須是 public abstract | 抽象類中抽象方法的訪問(wèn)權(quán)限修飾符可以是public润歉、protected模狭、default |
接口中定義的屬性必須是 public static final 常量 | 抽象類中可以有普通變量和靜態(tài)變量(static) |
接口中沒(méi)有構(gòu)造方法 | 抽象類中有構(gòu)造方法 |
內(nèi)部類
1、內(nèi)部類——就是定義在另一個(gè)類內(nèi)部的類踩衩。
2嚼鹉、注意
(1)內(nèi)部類可以訪問(wèn)其外部類所有的屬性和方法。
(2)無(wú)需創(chuàng)建外部類對(duì)象驱富,即可從內(nèi)部類訪問(wèn)外部類的屬性和方法锚赤。
(3)必須創(chuàng)建內(nèi)部類的對(duì)象,否則無(wú)法從外部類訪問(wèn)內(nèi)部類的屬性和方法褐鸥。
(4)如果內(nèi)部類有和外部類重名的屬性或方法线脚,則內(nèi)部類的屬性或方法會(huì)優(yōu)先使用。
(5)不能夠定義static變量叫榕。
(6)先創(chuàng)建好外部類浑侥,通過(guò)外部類的對(duì)象(引用)才能創(chuàng)建內(nèi)部類。
//如果內(nèi)部類有和外部類重名的屬性或方法晰绎,則內(nèi)部類的屬性或方法會(huì)優(yōu)先使用寓落。
public class OuterClass2 {
int outer = 100;
double x =3.14;
//內(nèi)部類
class InnerClass2{
int inner = 200;
double x = 3.1415926;
public void showOuter(){
System.out.println(outer);//外部類變量
System.out.println(x); //內(nèi)部類變量?jī)?yōu)先級(jí)高
//訪問(wèn)變量同名的外部類變量
System.out.println(OuterClass2.this.x);
}
}
public void showInner(){
InnerClass2 innerClass2 = new InnerClass2();
innerClass2.showOuter();
}
public static void main(String[] args) {
OuterClass2 outerClass2 = new OuterClass2();
outerClass2.showInner();
}
}
3、內(nèi)部類的訪問(wèn)權(quán)限修飾符
——普通類的訪問(wèn)權(quán)限修飾符:public荞下、default
——內(nèi)部類的訪問(wèn)權(quán)限修飾符:public零如、protected、default锄弱、private
4考蕾、內(nèi)部類的訪問(wèn)
—先創(chuàng)建好外部類,通過(guò)外部類的對(duì)象(引用)才能創(chuàng)建內(nèi)部類
OuterClass outerClass = new OuterClass(); //實(shí)例化外部類
InnerClass innerClass = outerClass.new InnerClass(); //實(shí)例化內(nèi)部類
public class OuterClass {
int a;
public void add(){
System.out.println("OuterClass=add");
}
//內(nèi)部類
class InnerClass{
int b;
public void add(){
System.out.println("InnerClass=add");
}
}
public static void main(String[] args) {
//先創(chuàng)建好外部類会宪,通過(guò)外部類的對(duì)象(引用)才能創(chuàng)建內(nèi)部類
OuterClass outerClass = new OuterClass();
outerClass.add();
//通過(guò)外部類的對(duì)象(引用)創(chuàng)建內(nèi)部類
InnerClass innerClass = outerClass.new InnerClass();
innerClass.add();
}
}
5肖卧、靜態(tài)內(nèi)部類
——用 static 標(biāo)識(shí)的內(nèi)部類為靜態(tài)內(nèi)部類
(1)靜態(tài)內(nèi)部類作為外部類的靜態(tài)成員,不能訪問(wèn)外部類非靜態(tài)成員掸鹅。
(2)非靜態(tài)內(nèi)部類只能定義非靜態(tài)成員塞帐,而靜態(tài)內(nèi)部類可以定義靜態(tài)成員和非靜態(tài)成員。
(3)使用 OuterStatic.InnerStatic in = new OuterStatic.InnerStatic() 方式實(shí)例化靜態(tài)內(nèi)部類巍沙。
//靜態(tài)內(nèi)部類
public class OuterStatic {
int outer = 100;
static int outer2 = 300;
static class InnerStatic{
static int a;
int inner = 200;
public void showOuter(){
//System.out.println(outer);
System.out.println(outer2);
}
}
public void showInner(){
InnerStatic innerStatic = new InnerStatic();
System.out.println(innerStatic.inner);
}
public static void main(String[] args) {
//創(chuàng)建外部類
OuterStatic outerStatic = new OuterStatic();
//創(chuàng)建靜態(tài)內(nèi)部類
OuterStatic.InnerStatic in = new OuterStatic.InnerStatic();
in.showOuter();
}
}