抽象類
定義:用關鍵字abstract關鍵字類修飾的一個類,叫做抽象類。
abstract class ClassName{
}
注意:1、抽象類必須被繼承。
2、抽象類不能直接執行個體化。它隻能作為超類,這一點與最終類(final類)正好相反。
3、抽象類中可以有抽象方法與普通方法,但抽象方法必須在抽象類中。
抽象方法
定義:用abstract來修飾的一個方法,叫做抽象方法。
abstract class ClassName{
abstract returnType abstractMethod([paramlist]);
}
注意:1、抽象方法必須被重寫;
2、抽象方法在抽象類中隻能聲明,不能實作。即不能有{}。
3、定義抽象方法的類必須是抽象類。
4、子類繼承抽象類時,必須重寫所有的抽象方法子類才能成為普通類,不然子類也是抽象類。
例如:注意4例子
abstract class Animal{
abstract void eat();
abstract void sleep();
}
abstract class Dog extends Animal{
public void eat() {//抽象父類eat方法,但未重寫sleep方法
//是以子類Dog也是一個抽象類。
}
// public void sleep() {
//
// }
}
接口
定義:接口就是方法定義與常量的集合。 從文法上講:接口是一種特殊的抽象類,這種抽象類中隻包含常量和方法的的定義,沒有方法的實作(沒有普通方法和普通變量)。
實作:用interface關鍵字實作。
[public] interface interfaceName [extends Super Interface1, SuperInterface2,…]{
}
public class InterfaceTest {
public static void main(String[] args) {
student stu=new student();
stu.sleep();
System.out.println(stu.a);//輸出接口person裡面的常量
}
}
class student implements Agenf{//接口的使用,關鍵字implements
public student() {
}
@Override
public void eat() {
System.out.println("吃飯!!");
}
@Override
public void sleep() {
System.out.println("睡覺!!!");
}
}
interface person{
int a=10;
void eat();
}
interface Animal1{//聲明接口
int b=100;
void sleep();
}
interface Agenf extends person,Animal1{//繼承兩個接口
@Override
default void sleep() {//按道理說這裡是不可以實作方法的
//因為接口裡面應該隻有方法的聲明,不能有實作。
//但這樣也沒有錯,我也不知道為何!
}
@Override
default void eat() {
}
}
特點:1、與類的繼承不同,一個接口可以繼承多個父接口;
2、一個public接口隻能定義在同名的.java檔案中
接口的使用
1、用implements關鍵字來表示一個類的使用某個接口;
2、類可以使用接口定義的常量,但必須實作接口中定義的所有方法;
3、接口可以實作多重繼承,即繼承多個接口;
4、接口作用與抽象類相似,隻定義原型,不直接定義方法内容;
5、接口中的方法和常量必須是public。
interface person{//其實是public interface peerson
int a=10;//public static final int a=10;
//public static final 省略
/* public abstract 省略 */ void eat();
}
JAVA8接口的新特性
java8允許我們給接口添加一個非抽象的方法實作,并且有方法體,隻需使用關鍵字default或者static 即可,這個特征又叫擴充方法
//解釋了上面代碼裡遺留的問題
interface Agenf{
default void sleep() {//按道理說這裡是不可以實作方法的
//但是Java8過後可以,擴充特性。
}
@Override
default void eat() {
}
}
注意事項(重寫規則):
1、子類繼承的多個接口中同時存在同名,同參數的靜态方法。子類在調用父類的靜态方法的時候,需要通過父類名.靜态方法名。若該靜态方法如果在子類中也定義,它是不算被重寫的。
2、如果兩個接口的方法名和參數相同都是default方法,裡面的實體不同,在子類中需要重寫。
3、如果兩個接口中的方法名,參數都相同的方法,一個接口是抽象方法,一個是default修飾的方法體。在類中也必須被重寫。
4、如果一個類實作了一個接口的預設方法,同時又繼承了另外一個類的方法。那麼子類的方法優先跟父類的方法行為一緻。
抽象類與接口異同點
相同點:
1、都必須通過其他類才能實作;
2、不能直接執行個體化。
不同:
1、抽象類是類,可包含變量及抽象方法的定義;
2、接口實質不是類,隻含有類常量以及抽象方法的定義;
3、類隻能單一繼承,接口可以多繼承。
4、接口隻能public修飾符,類可以是任意修飾符;
5、繼承強調關系:is a 接口強調功能: has a
内部類
定義:定義在類内部的類稱為内部類,可以直接通路外圍類相關成員。
說明:内部類編譯後也會形成一個單獨的.class,但它附屬于其包含類。
分類:類體中的内部類 和 方法體中的内部類
一、類體中的内部類:
相當于類體中的成員變量,可以在類的内部和外部使用。
指令格式: 外圍類類名+$+内部類類名.class
靜态内部類:static 修飾,隻能通路外圍類靜态的成員。
執行個體内部類:可以通路外圍類所有成員。
執行個體内部類:
public class TestInnerClass {
public static void main(String[] args) {
Outer ou=new Outer();
//建立内部類對象
Outer.Inner inner=new Outer().new Inner();
inner.show();
}
}
class Outer{
private int age=10;//外部類成員變量
public void testOuter() {
System.out.println("這是外部類!");
}
class Inner{//普通内部類不能用static方法和屬性
private int age=20;//内部類成員變量
public void show() {
int age=30;//方法成員變量
System.out.println("外部内的成員變量age:"+Outer.this.age);
System.out.println("内部内的成員變量age:"+this.age);
System.out.println("方法成員變量age:"+age);
}
}
}
靜态内部類:
public class OuterTest2 {
public static void main(String[] args) {
//靜态内部類的建立
Outer2.Inner2 inner2=new Outer2.Inner2();
}
}
class Outer2{
static class Inner2{
}
}
二、方法體中的内部類:隻能在定義它的方法中或者代碼塊中使用,不能在外部使用。(又可以細分為有名字的内部類和匿名内部類)
命名格式:外圍類名字+ + 數 字 + 内 部 類 類 名 . c l a s s 外 圍 類 類 名 + + 數字+内部類類名.class 外圍類類名+ +數字+内部類類名.class外圍類類名++數字.class
匿名内部類:
public class TestInn {
public static void test01(AA a) {
System.out.println("---------");
a.aa();
}
public static void main(String[] args) {
TestInn.test01(new AA() {//匿名内部類,隻能使用一次
public void aa() {
System.out.println("new AA(){}");
}
});
}
}
interface AA{
void aa();
}
注意:匿名内部類沒有通路修飾符,沒有構造方法。
三、何時使用内部類
1、當第一個類能直接通路另外一個類中的成員時,将一個類定義為另一個類的内部類。
2、用于處理在GUI部分的事件處理機制中。
好處:可以直接使用包含類的變量和方法。(内部類隻能在包含它的類中使用,同時把它看作該包含類的一段特殊代碼。)