接口
1、接口的定义
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构;二,一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做”Java接口”,后者叫做”接口”。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只有包含常量和方法的定义,而没有变量和方法的实现。
格式:interface 接口名称{ }
2、接口的成员修饰符是固定的。
成员常量:public static final
成员函数:public abstract
3、接口注意事项:
发现接口中的成员都是public,接口的出现将“多继承”通过另一种形式体现出来,即多实现。
当一个抽象类中全是抽象方法时,这时将该抽象类用另一种形式,就是接口interface。
定义接口使用的关键字不是class,而是interface。
接口中的成员全部是公共权限。
类与类之间是继承关系,而类与接口之间是实现关系,接口与接口之间是继承关系。
接口不可以实例化,只能由实现了接口的子类并覆盖了接口中的所有抽象方法之后,该子类才可以被实例化,否则该子类仍为抽象类。
一个类在继承另一个类的同时,还可以实现多个接口。
接口克服了单继承的局限性。
接口与接口之间是继承关系,而且接口可以实现多继承。
4、接口特点:
接口是对外暴露的规则,是程序功能的扩展,降低耦合性,可以用多实现。
5、接口的实现类:
与抽象类一样,接口要使用也必须通过子类,子类通过implements关键字实现接口 ,
一个类可以实现多个接口,在implements语句中用逗号隔开。
非抽象子类必须实现接口中定义的所有方法(抽象方法)。
实现格式:
class 子类 implements接口A,接口B…{
}
6、接口的使用规则
接口中所有的方法都是public abstract。
在接口中声明方法时,不能使用static,final,synchronized,private,protected等修饰符。
一个接口可以继承另一个接口。
Java中不允许类的多继承,但是允许接口的多继承。
接口中可以有数据成员,这些成员默认都是public static final
7、接口的用途
用处:
(1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系.。
(2)通过接口指明多个类共同需要实现的方法、
(3)通过接口了解对象的交互界面,而无需了解对象所对应的类。
8.在实际开发中不同类型的多态的使用情况
接口多态(最多)
抽象类多态(比较多)
具体对象的创建(经常会使用)
代码示例
package org.westos;
interface AnimalTrain{
//接口中的方法不能有方法体,只能是抽象方法
public abstract void jump() ;
public abstract void speak() ;
}
interface Speak{
public abstract void speak() ;
}
class Cat{}
class JumpCatImpl extends Cat implements AnimalTrain{
@Override
public void jump() {
System.out.println("部分猫可以跳高了...");
}
@Override
public void speak() {
System.out.println("猫开口说话了...");
}
}
public class AbstractDemo11 {
public static void main(String[] args) {
AnimalTrain at = new JumpCatImpl() ;//接口多态(实际开发中用的最多)
at.jump();
at.speak();
}
}
代码示例
package org.westos;
import java.util.zip.InflaterInputStream;
interface Inter{
int num1=100;
public static final int num2 = 200 ;
public abstract void method();
public abstract void eat();
}
//子实现类
class InterImpl implements Inter{
public void show() {
System.out.println("我是show方法");
}
@Override
public void eat() {
System.out.println("我要吃!!!");
}
@Override
public void method() {
System.out.println("我是方法!!!");
}
}
public class AbstractDemo11 {
public static void main(String[] args) {
Inter i = new InterImpl() ;
System.out.println(Inter.num1); //能够使用此语句,说明当前变量被static所修饰
System.out.println(Inter.num2);
i.eat();
i.method();
InterImpl a=new InterImpl();
a.show();
}
}
教练和运动员案例
乒乓球运动员和篮球运动员。
乒乓球教练和篮球教练。
为了出国交流,跟乒乓球相关的人员都需要学习英语。
请用所学知识:
分析这个案例有哪些抽象类,有哪些接口,有哪些具体类。
自己提供一些属性,测试一下
Person类(抽象类)代码
package org.westos2;
public abstract class Person {
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
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();//eat()为抽象类,在子类中进行重写(override)
}
Speaking接口
代码
package org.westos2;
public interface Speaking {
public abstract void speakEnglish();
}
Player类(抽象类) 代码
package org.westos2;
public abstract class Player extends Person {
public Player() {
super();
// TODO Auto-generated constructor stub
}
public Player(String name, int age) {
super(name,age);
// TODO Auto-generated constructor stub
}
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("运动员爱吃汉堡!!!");
}
}
Coach类(抽象类) 代码
package org.westos2;
public abstract class Coach extends Person {
public Coach() {
super();
// TODO Auto-generated constructor stub
}
public Coach(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("教练爱吃潼关肉夹馍!!!");
}
}
PingPangPlayer类 代码
package org.westos2;
public class PingPangPlayer extends Player implements Speaking {
public PingPangPlayer() {
super();
// TODO Auto-generated constructor stub
}
public PingPangPlayer(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@Override
public void speakEnglish() {
// TODO Auto-generated method stub
System.out.println("乒乓球运动员会说英语");
}
public void study() {
System.out.println("乒乓球运动员学习如何接球和发球");
}
}
PingPangCoach类 代码
package org.westos2;
public class PingPangCoach extends Coach implements Speaking {
public PingPangCoach() {
super();
// TODO Auto-generated constructor stub
}
public PingPangCoach(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@Override
public void speakEnglish() {
// TODO Auto-generated method stub
System.out.println("乒乓球教练会说英语!!!");
}
public void teach() {
System.out.println("乒乓球教练教乒乓球运动员如何接球和发球");
}
}
BasketPlayer类 代码
package org.westos2;
public class BasketPlayer extends Player{
public BasketPlayer() {
super();
// TODO Auto-generated constructor stub
}
public BasketPlayer(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
public void study() {
System.err.println("篮球运动员学习如何传球和运球");
}
}
BasketCoach类 代码
package org.westos2;
public class BasketCoach extends Coach implements Speaking {
public BasketCoach() {
super();
// TODO Auto-generated constructor stub
}
public BasketCoach(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@Override
public void speakEnglish() {
// TODO Auto-generated method stub
}
public void teach() {
System.out.println("篮球教练交篮球运动员如何运球和传球");
}
}
TestDemo类(测试类) 代码
package org.westos2;
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
PingPangPlayer pangPlayer=new PingPangPlayer("张三", 27);
System.out.println("姓名:"+pangPlayer.getName()+" "+"年龄:"+pangPlayer.getAge());
pangPlayer.eat();//没有在PingPangPlayer类中找到eat()方法,则调用的是父类player中的eat()方法
pangPlayer.study();
pangPlayer.speakEnglish();
}
}
形式参数的问题:
形式参数是基本类型,对实际参数没有影响(简单)
形式参数是引用类型:
类(普通类)
抽象类 (abstract)
1.形式参数为普通类
代码示例
package org.westos;
class Student{
public void study() {
System.out.println("Good Good Study,Day Day Up...");
}
}
class StudentDemo{
//成员方法
public void method(Student s) {
s.study();
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
StudentDemo sd = new StudentDemo() ;
//需要创建Student的对象
sd.method(new Student());
System.out.println("----------------");
//链式编程 使用匿名对象
//匿名对象是可以作为参数传递的
new StudentDemo().method(new Student());
}
}
2.形式参数为抽象类
代码示例
abstract class Person{
public void teach() {
System.out.println("今天天气不错,适合踢球...");
}
}
class PersonDemo{
public void method(Person p) { //不能直接创建对象 Person p =new Person(); 可以采用抽象类多态的形式实现
p.teach();
}
}
//需要提供Pereson类的子类
class Teacher extends Person{
}
//测试类
public class TeacherTest {
public static void main(String[] args) {
//需求:需要调用PersonDemo类中的method()方法
//创建PersonDemo对象
PersonDemo pd = new PersonDemo() ;
// Perosn p = new Person() ; //错误的,抽象类是不能实例化的
Person p = new Teacher();//可以通过父类引用指向子类对象的方式进行实例化
pd.method(p);
}
}
3.形式参数是接口
代码示例
interface Inter{
public abstract void study() ;
}
class InterDemo{
public void show(Inter i) { //需要创建该接口对象,不能直接实例化 Inter i = new Inter() ;错误的
//需要提供接口的子实现类,可以通过子实现类进行实例化:接口多态...
i.study();
}
}
//子实现类
class Student2 implements Inter{//Student2为接口Inter的子实现类
@Override
public void study() {
System.out.println("Good Good Study,Day Day Up!!!");
}
}
//测试类
public class StudentTest {
public static void main(String[] args) {
//需求:需要调用InterDemo这个了中的show()方法,如何调用
//创建InterDemo类的对象
InterDemo id = new InterDemo() ;
Inter i = new Student2() ;//以接口多态的形式创建Inter对象
id.show(i);
}
}
返回值:
如果返回值为基本类型:用对应的基本类型数据去接收即可!
引用类型:
类(具体类):
需要的是该类的对象
抽象类
接口
1.返回值类型为普通类类型
代码示例
class Student3 {
public void study() {
System.out.println("Good Good Study ,Day Day Up ...");
}
}
class StudentDemo3 {
public int show() {
return 100;
}
public Student3 method() {// 该方法返回值为具体类,需要提供该具体类的对象
// 匿名对象的方式
// return new Student3();
Student3 s = new Student3();
return s;
}
}
// 测试类
public class PersonTest2 {
public static void main(String[] args) {
// 调用StudentDemo3中的metohd方法
Student3 s1 = new StudentDemo3().method();// method()方法返回值为Student3类的对象
s1.study();
System.out.println("-------------------");
StudentDemo3 sd = new StudentDemo3();
Student3 s2 = sd.method();
s2.study();
System.out.println("-------------------");
}
}
2.返回值类型为抽象类类型
代码示例
abstract class Person2{
public void show() {
System.out.println("今天天气不错");
}
}
class PersonDemo2{
public Person2 method() {
//返回值是一个抽象类
// return new Person2() ; 抽象类不能实例化 ,需要提供该抽象类的子类
//抽象类多态的形式创建对象
// Person2 p = new Teacher2() ;
// return p ;
return new Teacher2() ; //匿名对象,通过子类进行实例化(向上转型)
}
}
class Teacher2 extends Person2{
}
//测试类
public class StudentTest2 {
public static void main(String[] args) {
PersonDemo2 pd = new PersonDemo2() ;
Person2 p = pd.method() ; // Person2 p = new new Teacher2() ;
p.show();
}
}
3.返回值类型为接口类型
代码示例
interface Inter2{
public abstract void study();
}
class InterDemo2{
public static Inter2 method() {
// return new Inter2(); 接口不能实例化,提供接口的子实现类
// return new InterImpl() ; //匿名对象的方式
Inter2 i = new Inter2Impl();//接口多态
return i;
}
}
class Inter2Impl implements Inter2{//接口Inter2的子实现类
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
}
public class TeacherTest2 {
public static void main(String[] args) {
InterDemo2 id = new InterDemo2() ;
Inter2 i1 = id.method() ; //Inter2 i = new InterImpl() 接口多态的形式
i1.study();
Inter2 i2 =new InterDemo2().method() ;
}
}
内部类
在B类内部定义A类,A类就属于B的内部类
内部类访问外部类的特点:
外部类如何访问内部类的成员?
通过创建内部类对象的方式间接访问
代码示例
package org.westos;
class Outer{
int num = 222 ;
private int num2 = 666 ;
//Inner就是Outer的内部类
class Inner{
//内部类的方法
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
//外部类的成员位置
public void method() {
Inner i = new Inner() ;//创建内部类对象
i.show();
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer outer=new Outer();
outer.method();
}
}
内部类的分类:
1)成员内部类:在外部类的成员位置。
2)局部内部类:在外部类的局部位置。
代码示例
class Outer2 {
// 在成员位置:成员内部类
class Inner2 {
}
public void method() {
// 在局部位置:局部内部类
class Inner {
}
}
}
实际开发中,接口作为形式参数的问题
1)提供接口的子实现类
代码示例
nterface Inter2{
public abstract void study();
}
//具体类
class StudentDemo{
public void method(Inter2 i) {//Inter2 i = new Inter2() ;//错误
i.study();
}
}
class InterImpl2 implements Inter2{
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
}
//测试类
public class Demo {
public static void main(String[] args) {
//需求:需要调用StudentDemo这个类中method()方法
StudentDemo sd = new StudentDemo() ;
Inter2 i = new InterImpl2() ;//接口多态的形式
sd.method(i);
System.out.println("---------------");
//链式编程:匿名对象
new StudentDemo().method(new InterImpl2());
System.out.println("----------------");
Inter2 i2 = new Inter2() {
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
};
i2.study();
}
}
成员内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类(非静态的内部类)的成员方法:
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象
代码示例
package org.westos;
class Outer3{
//外部类的成员变量
private int num = 666 ;
//成员内部类
class Inner3{
public void show() {
System.out.println(num);
}
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer3.Inner3 oi = new Outer3().new Inner3();
oi.show();
}
}
关于成员内部类的修饰符:
特点:
静态成员内部类访问外部类的数据,该数据必须被static修饰
对于静态成员内部类的访问格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名() ; //把静态成员内部类看成是外部类的成员
代码示例
package org.westos;
class Outer4{
private int num = 10 ;
private static int num2 = 100 ;
//静态成员内部类
static class Inner4{
//成员方法
//非静态内部类的成员方法
public void show() {
//System.out.println(num); //静态成员内部类访问外部类的数据,该数据必须被static修饰
System.out.println(num2);//num2被static修饰i
}
//静态内部类的成员方法
public static void show2() {
// System.out.println(num);
System.out.println(num2);
}
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer4.Inner4 oi = new Outer4.Inner4() ;
oi.show();
oi.show2();
}
}
局部内部类可以访问外部类的成员包括私有
在外部类的局部位置去访问内部类的show(),需要在局部位置去创建内部类对象,通过内部类对象去访问show()。
代码示例
package org.westos;
class Outer{
private int num=10;
public void method() { //外部类的成员方法
final int num2=111; //局部final变量
class Innner{
public void show() {
System.out.println("外部类私有数据:"+num);
System.out.println("局部final变量:"+num2);
}
}
Innner i=new Innner();
i.show();
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer outer=new Outer();
outer.method();
}
}
匿名内部类
前提是有类或者接口
这个类可以是具体类也可以是抽象类
new 类名或者接口名{
方法重写();
}
匿名内部类的本质:
继承了该类,进行方法重写或者实现了该接口的子实现类,进行方法重写
代码示例
interface Inter{
public abstract void show();
public abstract void show2() ;
}
//定义一个类实现这接口...
class Outer6{
//成员方法
public void method() {
//调用接口一个方法的时候:匿名内部类的形式
/*new Inter() {
@Override
public void show() {
System.out.println("show...");
}
}.show();*/
//两个方法调用
/* new Inter() {
@Override
public void show2() {
System.out.println("show2....");
}
@Override
public void show() {
System.out.println("show...");
}
}.show();
new Inter() {
@Override
public void show2() {
System.out.println("show2....");
}
@Override
public void show() {
System.out.println("show...");
}
}.show2();*/
//上述非常麻烦:直接创建对象,给它起名字
Inter i = new Inter() {
@Override
public void show2() {
System.out.println("show2...");
}
@Override
public void show() {
System.out.println("show....");
}
};
i.show();
i.show2();
}
}
public class OuterDemo6 {
public static void main(String[] args) {
//创建Outer6类的对象
Outer6 o = new Outer6() ;
o.method();
}
}
匿名内部类面试题:
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
代码示例
interface Inter3{
void show() ;//public abstract
}
class Outer7{
//补齐代码
public static Inter3 method() {
//返回的是接口:当前并不提供接口的子实现类,所以只能用匿名内部类
return new inter3 {//method()返回值 匿名内部类
public void show() {//对show()进行方法重写
System.out.println("Helloworld");
}
};
}
}
//测试类
public class Test {
public static void main(String[] args) {
Outer7.method().show();
}