小楊初學Java的筆記16
一、介面
1、介面的特點:
1)、介面使用關鍵字:interface表示
定義格式:interface 介面名{}
2)、類實現介面用
定義格式:class 類名 implements 介面名{}
3)、介面不能例項化
那麼如何表示介面的實現呢?
使用多型的方式實現,有具體的子類進行例項化,其實這是多型的一種,介面多型
4)、介面子類的特點
如果子類是一個抽象類,那麼可以不需要重寫介面中的方法
如果子類是一個具體的類,必須要重寫介面中所有抽象方法
5)、到目前為止,我們學過三種多型方式:
a、具體類中的多型 (最後才是這個)
b、抽象類中的多型 (其次是抽象多型)
c、介面中的多型 (是最常見的,介面開發)
6)、舉例
檢視程式碼
abstract class Animal{ private String name; private int age; public Animal() { } public Animal(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 abstract void eat(); } class Cat extends Animal{ public Cat() { } public Cat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println("貓吃魚"); } } //定義一個介面,表示鑽火圈 interface DrillFire{ public void zuanHuo(); } //定義訓練過具體的貓的類實現鑽火圈介面 class TrainCat extends Cat implements DrillFire{ @Override public void zuanHuo() { System.out.println("貓跳著鑽火圈"); } } //定義一個抽象類實現鑽火圈介面 abstract class Demo implements DrillFire{ } public class InterfaceDemo1 { public static void main(String[] args) { // DrillFire df = new DrillFire(); //報錯,介面不能例項化 DrillFire df = new TrainCat(); } }
2、介面成員的特點
介面成員的特點:
成員變數:
只能是常量,並且是靜態的
它裡面給成員變數的預設修飾符是public static final
建議:手動全部補齊
構造方法:
介面中沒有構造方法
成員方法:
介面中的成員方法只能是抽象方法,沒有方法體,連大括號都沒有
它會自動補充修飾符:public abstract
建議:手動全部補齊
舉例:
檢視程式碼
interface Inter{ int a = 10; //它會自動補全為public static final int a = 10; public static final int b = 20; /*Inter(){} Error:(20, 22) java: 介面抽象方法不能帶有主體 public void fun(){ System.out.println("玩遊戲"); Java:介面中的方法不能有主體 }*/ public void fun(); } /*雖然介面中沒有構造方法,但是多型初始化的時候要先初始化子類再初始化父類 這裡其實繼承了一個父類,java中所有的類都預設繼承一個類:Object 每一個class都有Object作為超類 那麼所有繼承Object類的實現物件都實現了這個類中的方法 */ class Demo1 extends Object implements Inter{ @Override public void fun() { System.out.println("玩遊戲2"); } } public class InterfaceDemo2 { public static void main(String[] args) { Inter i = new Demo1(); //Error:(24, 10) java: 無法為最終變數a分配值 //i.a = 100; System.out.println(i.a); //System.out.println(Inter.a); 不報錯,輸出為10 } }
3、介面、類之間的關係
類與類,類與介面,介面與介面之間的關係
類與類:
繼承關係,只能進行單繼承,不可以進行多繼承,但是可以多層繼承
類與介面:
實現關係,可以是單實現,也可也一次實現多個介面,也可以在繼承一個類的同時,實現多個介面。
介面與介面之間的關係:
繼承關係,可以單繼承,也可以多繼承。
class A{}
class B extends A{}
interface Inter3{}
interface Inter2{}
class C extends A implements Inter2, Inter3{}
interface Inter4 extends Inter2,Inter3{}
public class InterfaceDemo3 {
}
4、介面練習
/*貓狗案例,加入額外的跳高功能
分析:
貓:姓名,年齡,吃飯,睡覺
狗:姓名,年齡,吃飯,睡覺
由於貓和狗存在共性,所以我們提取出來到一個抽象類中
動物:姓名,年齡,吃飯(),睡覺()
貓:繼承自動物
狗:繼承自動物
由於跳高是一個額外的功能,不是動物特有的,所以我們利用介面的方式定義
介面:
跳高
部分的貓:實現介面
部分的狗:實現介面*/
檢視程式碼
abstract class Animal3{
private String name;
private int gae;
public Animal3() {
}
public Animal3(String name, int gae) {
this.name = name;
this.gae = gae;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGae() {
return gae;
}
public void setGae(int gae) {
this.gae = gae;
}
//抽象方法
public abstract void eat();
public abstract void sleep();
}
class Cat3 extends Animal3{
public Cat3() {
}
public Cat3(String name, int gae) {
super(name, gae);
}
@Override
public void eat() {
System.out.println("貓吃魚");
}
@Override
public void sleep() {
System.out.println("貓趴著睡");
}
}
class Dog3 extends Animal3{
public Dog3() {
}
public Dog3(String name, int gae) {
super(name, gae);
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public void sleep() {
System.out.println("狗側著睡");
}
}
//定義跳高的介面
interface Jump{
public abstract void jump();
}
//定義部分會跳高的貓
class JumpCat extends Cat3 implements Jump{
public JumpCat() {
}
public JumpCat(String name, int gae) {
super(name, gae);
}
@Override
public void jump() {
System.out.println("貓跳高");
}
}
//定義部分會跳高的狗
class JumpDog extends Dog3 implements Jump{
public JumpDog() {
}
public JumpDog(String name, int gae) {
super(name, gae);
}
@Override
public void jump() {
System.out.println("狗跳高");
}
}
public class InterfaceTest1 {
public static void main(String[] args) {
//建立不會跳高的狗
Animal3 a1 = new Dog3("小白",2);
a1.eat();
a1.sleep();
//建立一個會跳高的狗
Dog3 d1 = new JumpDog("大黃",3);
d1.eat();
d1.sleep();
((JumpDog) d1).jump();
Jump j1 = new JumpDog("小黑",4);
((JumpDog) j1).eat();
((JumpDog) j1).sleep();
j1.jump();
}
}
二、形式引數和返回值型別問題
1、形式引數:
基本資料型別:byte、short、int、long、float、double、char、boolean(略)
引用資料型別:類、抽象類、介面、(陣列略)
1)、類:當類作為方法的形式引數的時候,實際上需要的該類的物件
檢視程式碼
abstract class Animal3{
private String name;
private int gae;
public Animal3() {
}
public Animal3(String name, int gae) {
this.name = name;
this.gae = gae;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGae() {
return gae;
}
public void setGae(int gae) {
this.gae = gae;
}
//抽象方法
public abstract void eat();
public abstract void sleep();
}
class Cat3 extends Animal3{
public Cat3() {
}
public Cat3(String name, int gae) {
super(name, gae);
}
@Override
public void eat() {
System.out.println("貓吃魚");
}
@Override
public void sleep() {
System.out.println("貓趴著睡");
}
}
class Dog3 extends Animal3{
public Dog3() {
}
public Dog3(String name, int gae) {
super(name, gae);
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public void sleep() {
System.out.println("狗側著睡");
}
}
//定義跳高的介面
interface Jump{
public abstract void jump();
}
//定義部分會跳高的貓
class JumpCat extends Cat3 implements Jump{
public JumpCat() {
}
public JumpCat(String name, int gae) {
super(name, gae);
}
@Override
public void jump() {
System.out.println("貓跳高");
}
}
//定義部分會跳高的狗
class JumpDog extends Dog3 implements Jump{
public JumpDog() {
}
public JumpDog(String name, int gae) {
super(name, gae);
}
@Override
public void jump() {
System.out.println("狗跳高");
}
}
public class InterfaceTest1 {
public static void main(String[] args) {
//建立不會跳高的狗
Animal3 a1 = new Dog3("小白",2);
a1.eat();
a1.sleep();
//建立一個會跳高的狗
Dog3 d1 = new JumpDog("大黃",3);
d1.eat();
d1.sleep();
((JumpDog) d1).jump();
Jump j1 = new JumpDog("小黑",4);
((JumpDog) j1).eat();
((JumpDog) j1).sleep();
j1.jump();
}
}
2)、抽象類:當抽象類作為方法的形式引數的時候,因為不能例項化所以使用多型的形式建立物件
abstract class Person{
public abstract void study();
}
class Student2 extends Person {
@Override
public void study() {
System.out.println("好好學習天天向上");
}
}
class PersonDemo{
//當一個抽象方法作為形式引數型別的時候,實際上需要的是子類實現物件的地址值,利用多型的性質
public void fun(Person person){ //Person person = new Student2()
person.study();
}
}
public class PersonTest {
public static void main(String[] args) {
/*
不使用匿名物件的時候
PersonDemo personDemo = new PersonDemo();
Person person = new Student2()
personDemo.fun(person);
*/
//匿名物件
PersonDemo personDemo = new PersonDemo();
personDemo.fun(new Student2());
}
}
3)、介面:當介面作為方法的形式引數的時候,使用介面多型的形式建立物件
檢視程式碼
interface Person2{
public abstract void study();
}
class Teacher implements Person2{
@Override
public void study() {
System.out.println("好好學習天天向上");
}
}
class TeacherDemo{
//當介面作為形式引數傳入的時候,實際上需要的是該介面的實現類的物件的地址值,利用介面多型的性質
public void fun(Person2 person2){ // Person2 person2 = new Teacher();
person2.study();
}
}
public class TeacherTest {
public static void main(String[] args) {
/*
不使用匿名物件的時候
TeacherDemo td = new TeacherDemo();
Person2 person2 = new Teacher();
td.fun(person2);
*/
//匿名物件
TeacherDemo td = new TeacherDemo();
td.fun(new Teacher());
}
}
2、返回值問題
基本資料型別:byte、short、int、long、float、double、char、boolean(略)
引用資料型別:類、抽象類、介面、(陣列略)
1)、類:當類作為方法的返回值的時候,實際上返回的是該的物件
檢視程式碼
class Student3{
public void study(){
System.out.println("好好學習天天向上");
}
}
class StudentDemo3{
public Student3 fun(){
//return new Student3();
//當類作為方法的返回值型別的時候,返回是實際上是該類物件的地址值
Student3 s = new Student3();
return s;
}
}
public class StudentTest2 {
public static void main(String[] args) {
StudentDemo3 sd = new StudentDemo3(); //先new一個StudentDemo3的物件呼叫方法,
Student3 s = sd.fun(); //把呼叫方法的返回值賦給s,再通過s呼叫fun()方法
s.study(); //這裡也可以寫成(new StudentDemo3()).fun().study()
}
}
2)、抽象類:當抽象類作為方法的返回值的時候,需要的是該抽象類子類的物件
檢視程式碼
abstract class Person3{
public abstract void study();
}
class Doctor extends Person3{
@Override
public void study() {
System.out.println("醫生學習醫術");
}
}
class PersonDemo3{
public Person3 getPerson(){
//抽象類不能例項化
Person3 person3 = new Doctor();
return person3;
}
}
public class PersonTest2 {
public static void main(String[] args) {
PersonDemo3 pd3 = new PersonDemo3();
Person3 person3 = pd3.getPerson(); //Person3 person3 = new Doctor();
person3.study();
}
}
3)、介面:當介面作為方法的返回值的時候,需要的是實現該介面的類的物件
檢視程式碼
interface PlayGame{
public abstract void playLoL();
}
class Teacher2 implements PlayGame{
@Override
public void playLoL() {
System.out.println("老師打英雄聯盟");
}
}
class TeacherDemo2{
public PlayGame getPlayGame(){
PlayGame pg = new Teacher2();
return pg;
}
}
public class TeacherTest2 {
public static void main(String[] args) {
/*一般寫法
TeacherDemo2 td2 = new TeacherDemo2();
PlayGame pg = td2.getPlayGame(); //PlayGame pg = new Teacher2();
pg.playLoL();
*/
//鏈式程式設計(後面大家會學習scala,spark,flink)
new TeacherDemo2().getPlayGame().playLoL();
}
}
三、導包以及許可權修飾符
1、導包
package:到達路徑為包
import:最終導的是一個類
package:放在java檔案的第一行,表示將來編譯執行的時候路徑
import:放在package和class之間的
class:是最後出現的,表示我們要寫的程式程式碼
2、許可權修飾符
許可權修飾符 | 同一類下 | 同一包子類,其他類 | 不同包子類 | 不同包其他類 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
預設 | √ | × | × | × |
private | √ | × | × | × |
3、類及其組成可以用的修飾符
修飾符:
訪問許可權修飾符:public,protected,預設,private
狀態修飾符:static,final
抽象修飾符:abstract
注:下面沒寫的修飾符就是不能修飾
類:
訪問許可權修飾符:預設,public(可以修飾,但是同一個Java檔案下只能有一個)
狀態修飾符:final
抽象修飾符:abstract
成員變數:
訪問許可權修飾符:預設,public, protected, private
狀態修飾符:static, final(可以修飾,需要在構造方法之前賦值)
構造方法:
訪問許可權修飾符:預設,public, protected, private
成員方法:
訪問許可權修飾符:public, 預設,protected,private
狀態修飾符:static, final
抽象修飾符:abstract(可以修飾,但是不能由有方法體,且只能在抽象類中使用抽象方法)
常見的修飾符組合:
成員變數:public static final 在介面中遇見
成員方法:
1、public abstract
2、public static
3、public final
將來做開發時,除了封裝必須使用private除外,如果不知道使用誰,就用public