接口


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();
	}
}

教练和运动员案例


          乒乓球运动员和篮球运动员。


          乒乓球教练和篮球教练。


          为了出国交流,跟乒乓球相关的人员都需要学习英语。


          请用所学知识:


          分析这个案例有哪些抽象类,有哪些接口,有哪些具体类。


                  自己提供一些属性,测试一下


java 接口面试 java接口基础知识_ide

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();
	}