JAVA基础知识面向对象之—接口与内部类
接口
-
A:接口的概念:
为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能。接口主要用来描述类具有什么功能,而并不给出每个功能的具体实现。
一个类可以实现一个或多个接口,并在需要接口的地方,随时使用实现了相应接口的对象。
接口不是类,而是一组对类的需求描述,这些类要遵从接口描述的统一格式进行定义。
-
B:接口特点:
a:接口用关键字interface表示 格式: interface 接口名 {}
b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
c:接口不是类,不能实例化
那么,接口如何实例化呢?---------按照多态的方式来实例化。
d:接口的子类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案) -
C:类实现接口的步骤:
1)将类声明为实现给定的接口;
2)对接口中的所有方法进行定义(重写)。
-
D:接口成员特点:
成员变量 : 只能是常量,并且是静态的。默认修饰符:public static final。(建议手动给出)
构造方法:接口没有构造方法。
成员方法:只能是抽象方法。默认修饰符:public abstract。(建议手动给出) -
案例演示:
public class MyTest { public static void main(String[] args) { Cat cat = new Cat(); Animal an = cat; an.eat(); CalcInterface calcInterface = cat; // CalcInterface 是猫的一个父接口,猫类也是父接口的一个子类 calcInterface.calc(); CalcInterface c = new Dog(); //多态,对接口进行实例化 c.calc(); //接口不能new 对象 } } // 接口,用来定义额外功能 public interface CalcInterface { //接口中只对方法进行声明 public abstract void calc(); } //父类 public abstract class Animal { public abstract void eat(); } //子类Cat类,继承Animal父类,实现接口CalcInterface public class Cat extends Animal implements CalcInterface{ @Override public void eat() { System.out.println("猫吃鱼"); } public void catcheMouse(){ System.out.println("猫抓老鼠"); } //对接口中的方法进行具体实现 @Override public void calc() { System.out.println("猫经过不断的努力学习,会做算术了"); } } //子类Dog类,继承Animal父类,实现接口CalcInterface public class Dog extends Animal implements CalcInterface{ @Override public void eat() { System.out.println("狗吃骨头"); } public void lookDoor(){ System.out.println("狗看门"); } //对接口中的方法进行具体实现 @Override public void calc() { System.out.println("狗经过自己的学习,也学会了做算术"); } }
接口与抽象类的区别:
- A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以常量
成员方法:只可以抽象 - B:关系区别
类与类 : 继承关系,只能单继承,可以多层继承。
类与接口 : 实现关系,可以单实现,也可以多实现。并且还可以在继承一个类的同时实现多个接口。
接口与接口 : 继承关系,可以单继承,也可多继承 - C:设计理念区别
抽象类 : 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 : 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
内部类
-
A:内部类概述:
把类定义在其他类的内部,这个类就被称为内部类。举例:在类A中定义了一个类B,类B就是内部类。
-
B:内部类访问特点:
a:内部类可以直接访问外部类的成员,包括私有。
b:外部类要访问内部类的成员,必须创建对象。 -
C:分类—按照内部类位置:
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。
成员内部类:
-
A:如何在测试类中直接访问内部类的成员。
格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象; -
案例演示:
定义成员内部类,并使用成员内部类的属性和方法。
public class MyTest { public static void main(String[] args) { Outer outer = new Outer(); System.out.println(outer.num); outer.outerShow(); System.out.println("--------------------------------"); //使用成员内部类的属性和方法 //创建成员内部类的语法 Outer.Inner inner=new Outer().new Inner(); System.out.println(inner.b); inner.innerShow(); System.out.println("---------------"); outer.method(); } } public class Outer { int num = 10; private int a = 100; //定义成员内部类 class Inner { int b = 109; public void innerShow() { System.out.println("内部类的show方法"); } //内部类可以直接访问外部类的成员,包括私有 public void innerTest(){ System.out.println(num); System.out.println(a); outerShow(); outerTest(); } } public void outerShow() { System.out.println("这是外部类的show方法"); } private void outerTest() { System.out.println("这是外部类的test方法"); } //外部类,想要访问内部类的成员,得创建内部类的对象 public void method(){ //创建内部类的对象 Inner inner = new Inner(); System.out.println(inner.b); inner.innerShow(); } }
10 这是外部类的show方法 -------------------------------- 109 内部类的show方法 --------------- 109 内部类的show方法
-
B:成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意事项: a:静态内部类访问的外部类数据必须用静态修饰。
b: 成员方法可以是静态的也可以是非静态的。 -
B:成员内部类被静态修饰后的访问方式是:
格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名(); -
案例演示:
成员内部类被private修饰。
public class MyTest { public static void main(String[] args) { //内部类被private修饰了,外界就不能直接创建内部类对象了 //Wai.Nei nei = new Wai().new Nei(); Wai wai = new Wai(); wai.waiShow(); } } class Wai{ //private修饰内部类 private class Nei{ int num=10; public void neiShow(){ System.out.println("内部类的show方法"); } } public void waiShow(){ Nei nei = new Nei(); System.out.println(nei.num); nei.neiShow(); } }
-
案例演示:
成员内部类被静态修饰。
public class MyTest { public static void main(String[] args) { //内部类被静态修饰后,创建内部类的语法要改变 Wai.Nei nei = new Wai.Nei(); } } class Wai { static int num = 10; private int a = 100; //成员内部类被static修饰 static class Nei { public void neiShow() { System.out.println(num); waiShow(); } } //静态内部类要访问外部类的成员只能访问静态的 public static void waiShow() { System.out.println("外部类的show方法"); } }
局部内部类:
-
A:局部内部类,外界不能直接创建其对象
-
B:局部内部类访问局部变量:
a: 可以直接访问外部类的成员,包括私有
b: 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
c:局部内部类访问局部变量必须用final修饰,为什么呢?
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。 -
案例演示:
局部内部类的创建与访问。
public class InnerClassDemo6 { public static void main(String[] args) { // 创建Outer的对象 Outer out = new Outer() ; // 调用show方法 out.show() ; } }
public class Out{ private int a = 45 ; public void show() { // 定义一个局部变量 final int b = 45 ;//JDK1.7之前要加final不然报错 但是在JDK1.8 不用加 不会报错 // 局部内部类 class Inner { public void method(){ System.out.println(a) ; System.out.println(b) ; } } // 创建对象 Inner i = new Inner() ; // 调用放 i.method() ; } }
匿名内部类:
-
A:匿名内部类 : 就是局部内部类的简化写法。
-
B:前提:存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
-
C:格式:
new 类名或者接口名(){
重写方法;
} ; -
D:本质是什么呢?
是一个继承了该类或者实现了该接口的子类匿名对象。 -
案例演示:
public class MyTest { public static void main(String[] args) { MyInterface myInterface = new BB(); myInterface.show(); myInterface.test(); //匿名内部类 new MyInterface(){ @Override public void show() { System.out.println("重写了接口中的show方法"); } @Override public void test() { System.out.println("重写了接口中test方法"); } }.show(); new MyInterface() { @Override public void show() { System.out.println("重写了接口中的show方法"); } @Override public void test() { System.out.println("重写了接口中test方法"); } }.test(); //给匿名内部类起个名字 MyInterface my = new MyInterface() { @Override public void show() { System.out.println("重写了接口中的show方法"); } @Override public void test() { System.out.println("重写了接口中test方法"); } }; //同一个对象,去调用两个方法 my.show(); my.test(); } } interface MyInterface{ void show(); void test(); } //ctrl+I 实现接口中的方法 class BB implements MyInterface{ @Override public void show() { System.out.println("重写了接口中的show方法"); } @Override public void test() { System.out.println("重写了接口中的test方法"); } }
-
案例演示:
内部接口的匿名调用。
public class MyTest { public static void main(String[] args) { //间接方式 Outer outer = new Outer(); outer.waiShow(); //直接方式 new Outer.Inner() { @Override public void show() { System.out.println("重写了接口中的show方法2222"); } }.show(); Outer.Inner inner= new Outer.Inner() { @Override public void show() { System.out.println("重写了接口中的show方法2222"); } }; inner.show(); inner.show(); } } class Outer{ //成员内部接口 interface Inner{ void show(); } public void waiShow(){ new Inner(){ @Override public void show() { System.out.println("重写了接口中的show方法"); } }.show(); } }
-
案例演示:
匿名内部类中的this关键字。
interface Inter { public static final int a = 23 ; } public class Test { public static void main(String[] args) { new Inter() { public void show() { // 这个this表示的是匿名内部类的这个对象 System.out.println(this.a); } }.show(); } }