關鍵字,修飾符 方法、類
當所有的子類對父類別的某個方法都進行了不同程度的重寫,那麼這個方法的方法體沒有實際含義就可以把方法體去掉,加上abstract關鍵字修飾方法-----抽象方法。一個類中如果出現了抽象方法那麼這個類就要變成抽象類。普通類繼承抽象類需要重寫所有的抽象方法,如果不想重寫所有的抽象方法可以把普通類變成抽象類。
package cn.tedu.abstractx;
public class AbstractDeno1 {
public static void main(String[] args) {
//物件是匿名內部類的物件
TuXing t = new TuXing(1,2) {
@Override
public double getGirth() {
return 0;
}
};//匿名內部類
}
}
//圖形類
//當類中出現抽象方法時類要變成抽象類
abstract class TuXing{
//定義私有屬性
private double a;
private double b;
//有參構造---通過有參構造給私有化屬性進行賦值
public TuXing(double a,double b){
this.a = a;
this.b = b;
}
//提供get方法間接獲取私有化屬性值
public double getA() {
return a;
}
public double getB() {
return b;
}
//提供周長面積計算方法
//抽象方法---1.沒有方法體 2.一定要重寫
public abstract double getGirth();
//public abstract double getGirth(int m);
/*{
return 0.0;//因爲沒有確切圖形不能使用具體計算公式
}*/
/*//普通方法----實體方法
public double getArea(){
return 0.0;//因爲沒有確切圖形不能使用具體計算公式
}*/
}
//矩形類
//當普通類繼承抽象方法需要重寫所有的抽象方法
//如果普通類不想重寫抽象類中所有的抽象方法可以變爲抽象類
abstract class JuXing extends TuXing{
//有參構造---呼叫父類別有參構造給父類別私有化屬性間接賦值
public JuXing(double a,double b){
super(a,b);
}
//重寫周長面積計算方法
/*public double getGirth(){
return 2*(getA()+getB());//求周長
}*/
public double getArea(){
return getA()*getB();//求面積
}
}
//正方形類
class ZhengFang extends JuXing{
//有參構造--呼叫父類別有參構造給父類別私有化屬性間接賦值
public ZhengFang(double a){
super(a,a);
}
//重寫周長面積計算方法
public double getGirth(){
return 2*(getA()+getB());//求周長
}
}
//圓形類
class Yuan extends TuXing{
//有參構造--呼叫父類別有參構造給父類別私有化屬性間接賦值
public Yuan(double r) {
super(r, r);
}
//重寫周長面積計算方法
public double getGirth(){
return 3.14*2*getA();//求周長
}
public double getArea(){
return getA()*getA()*3.14;//求面積
}
}
注意:
1.抽象方法可以過載?可以
2.抽象類裡一定含有抽象方法?不一定
3.抽象類中可以定義屬性以及普通方法?可以
4.抽象類可以定義構造方法?可以
5.抽象方法可以建立物件?抽象類沒有物件
6.抽象方法可以被private/static/final單獨修飾?不可以 因爲抽象方法一定重寫
7.抽象類可以被final修飾?不可以 最終類不能被繼承
8.抽象類目的就是爲了延展類的繼承結構
當抽象類中所有的方法都是抽象方法時,把抽象類變成介面來表示(用interface)。介面本質不是一個類,類和介面之間通過implements產生關聯關係—實現。Java支援介面與介面只減多繼承,類與介面之間多實現,就是爲了實現類能具有更多豐富的功能。實現類需要重寫介面所有的抽象方法,但是如果不想都重寫需要把實現類變成抽象類。
package cn.tedu.interfacex;
import java.io.Serializable;
public class InterfaceDemo1 {
public static void main(String[] args) {
System.out.println(Shape.i);
}
}
//代表圖形的類
//當抽象類裡都是抽象方法時可以把類轉成介面來表示
//介面本質不是類
//介面與介面之間支援多繼承
interface Shape extends Cloneable, Serializable {
//屬性,預設被public final static共同修飾
public final static int i = 1;
//抽象方法預設被public abstract修飾
public abstract double getGirth();
public abstract double getArea();
}
//代表矩形---普通類
//implements---代表類與介面之間的實現關係
//實現類
//類與介面之間支援多實現
//實現類需要把介面裏的所有抽象方法進行重寫,如果不想都重寫可以把實現類變爲抽象類
abstract class Rectangle implements Shape , Cloneable{
/* @Override
public double getGirth() {
return 0;
}*/
@Override
public double getArea() {
return 0;
}
}
package cn.tedu.interfacex;
public class InterfaceDemo2 {
public static void main(String[] args) {
//向上造型
B b=new C();
//編譯和執行都沒問題
//在做物件賦值時編譯時期和執行時期都會有對應的檢測
//在編譯時期會檢測兩個物件的宣告類是否有繼承關係
//c物件的宣告類是C類,b物件的宣告類是B類,此時有繼承關係則編譯通過
//在執行時期檢測兩個物件的實際建立類是否一致
//c物件實際建立類是C類,b物件實際建立類是C類,此時一致執行通過
C c=(C)b;//向下造型
//ClassCastException---型別轉換異常
//編譯沒有問題,執行有問題
//在編譯時期d物件宣告類是D類,b物件的宣告類是B類,有繼承關係則編譯通過
//在執行期間d物件的實際建立類是D類,b物件的實際建立類是C類不一致執行報錯
//D d=(D)b;
//編譯有問題
//在編譯時期d物件宣告類是D類,c物件的宣告類是C類此時沒有繼承關係則編譯錯誤
//d=(D)c;
//類與類之間單繼承(樹狀圖)可以快速確定兩者之間的關係,編譯時期會有對應的檢測
//類與介面之間是多實現(網狀圖)在確定兩者關係時需要耗費大量的資源,編譯時期沒有檢測
//但是在執行時期仍然有檢測,檢測實際建立類是否是介面的實現類。
A a=(A)b;
A a1=(A)c;
//
System.out.println("over~");
}
}
interface A{}
//C類和D類稱之爲同類
class B{}
class C extends B{}
class D extends B{}
注意:
1.介面裏的方法都是抽象方法?介面裏的方法都是抽象方法(和版本有關係)
2.介面裏可以定義構造方法?不能
3.介面可以建立物件?不能
4.介面裏可以定義屬性?可以定義,屬性預設被public final static共同修飾,抽象方法預設被public abstract共同修飾
5.介面宣告物件在編譯時期可以接收所有物件的型別物件的賦值,但是在執行時期檢測物件實際建立類是否是介面的實現類
6.介面的目的是讓實現類注入更多的特性
抽象類與介面的區別
1.介面不是類
2.介面裏面只有抽象方法
3.類與介面支援多實現,介面與介面支援多繼承
4.介面裏屬性和抽象方法有預設修飾符
5.抽象類有構造方法
6.抽象類爲了延展類的繼承結構,介面是爲了注入更多的特性
介面優點
模板、約束
類/介面裏定義類
類裡定義類
***方法內部類******
在方法內定義類
可以定義所有的非靜態資訊以及靜態常數
可以正常的繼承和實現
不能被存取許可權修飾符來修飾但是可以被abstract以及final來修飾
可以獲取外部類所有的資訊
只能獲取當前方法的常數資訊
package cn.tedu.inner;
public class InnerDemo1 {
public static void main(String[] args) {
//建立外部類物件呼叫方法執行建立內部類物件的語句
new Outer1().m();
}
}
//外部類
class Outer1{
//屬性
int k=1;
//方法
public void m(){
int y=1;//在jdk1.8以前定義常數需要手動加上final
//在jdk1.8及其以後定義變數時底層預設會新增final但是如果手動新增了
//底層就不再新增
y=3;
//方法內部類
//定義所有非靜態資訊以及靜態常數
//可以正常的繼承與實現
//不能被存取許可權修飾符來修飾但是可以被abstract以及final來修飾
//可以獲取外部類所有資訊
//只能獲取本方法的常數
class Inner1 extends Object implements Cloneable{
static final int x=1;
public void n(){
System.out.println(k);
//System.out.println(y);
}
}
System.out.println(y=5);
//建立方法內部類
Inner1 in1=new Inner1();
in1.n();
}
}
成員內部類
在成員位置定義類
可以定義所有的非靜態資訊以及靜態常數
可以正常的繼承和實現
可以被存取許可權修飾符以及abstract以及final來修飾
可以獲取外部類所有的資訊
package cn.tedu.inner;
import java.util.Scanner;
public class InnerDemo2 {
public static void main(String[] args) {
//Outer2.Inner2表示內部類
// Outer2.Inner2 inner2=new Outer2().in2;
//in2 = newInner2();
Outer2.Inner2 inner2=new Outer2().new Inner2();
}
}
//外部類
class Outer2{
//屬性
int k=1;
//非靜態屬性
//Inner2 in2 = new Inner2();
//成員內部類
//可以定義所有非靜態資訊以及靜態常數
//可以正常的繼承和實現
//可以讓存取許可權修飾符以及abstract和final來修飾
//可以獲取外部類所有的資訊
final class Inner2 extends Object implements Cloneable{
static final int x=1;
public void n(){
System.out.println(k);
m();
}
}
//方法
public void m(){}
}
靜態內部類
在成員內部類被static修飾
可以定義所有資訊
可以正常的繼承和實現
可以被存取許可權修飾符以及abstract以及final來修飾
可以獲取外部類的靜態資訊
package cn.tedu.inner;
public class InnerDemo3 {
public static void main(String[] args) {
//建立靜態內部類物件
Outer3.Inner3 inner3 = new Outer3.Inner3();
}
}
//外部類
class Outer3{
//屬性
static int k = 1;
//
static Inner3 in3=new Inner3();
//靜態內部類
//static修飾的類一定是內部類
//可以定義所有資訊
//可以進行正常的繼承和實現
//可以被存取許可權修飾符以及abstract和final修飾
//只能獲取外部類靜態資訊
static class Inner3 extends Object implements Cloneable{
static int x=1;
public void n(){
System.out.println(k);
}
}
//方法
public void m(){}
}
匿名內部類
用於繼承類/實現介面,重寫抽象方法
可以被繼承的類/介面都可以擁有匿名內部類的形式
匿名內部類只能使用一次
當做參數傳遞時來使用
package cn.tedu.inner;
public class InnerDemo4 {
public static void main(String[] args) {
//建立抽象類子類物件
/*D d=new D();
d.m();*/
//匿名內部類
//繼承類,重寫抽象方法,建立匿名內部類物件
//當類可以被繼承/是介面時,擁有匿名內部類的形式
//只能使用一次
C c=new C(){
@Override
public void m() {
System.out.println(1);
}
};
c.m();
//普通類也具有匿名內部類的形式
B b=new B(){};
//介面也具有匿名內部類的形式
A a=new A() {
};
//呼叫方法
//當作參數使用
m(new A(){});
}
//
public static void m(A a){//只能接收A介面的實現類物件
}
}
//介面
interface A{}
//普通類
class B{}
//
abstract class C{
public abstract void m();
}
class D extends C{
@Override
public void m() {
System.out.println(1);
}
}
介面裏定義類/內部介面預設都是被static修飾
package cn.tedu.inner;
public class InnerDemo5 {
public static void main(String[] args) {
System.out.println(Outer5.Inner5.i);
System.out.println(Outer5.Inner6.j);
System.out.println(Outer5.Inner5.Inner7.x);
}
}
interface Outer5{
//介面裏定義介面,預設被static修飾
interface Inner6{
int j=1;
}
//介面裏定義內部類預設被static修飾
static class Inner5{
static int i =1;
//類裡定義介面,預設被static修飾
static interface Inner7{
int x=1;
}
}
}