接口
接口的本质:
接口本质就是一个规则,定义接口就是定义规则,实现接口,相当于扩展功能。比如usb接口,就是为了扩展键盘,鼠标等功能。
接口的定义:
interface 接口名 {}
类实现接口:
class 类名 implements 接口名{}
接口特点:
成员变量:默认修饰符:public final static,因为默认有final,所以该变量就不能修改,所以就变成了成员常量。即接口中没有成员变量,只有成员常量。既然没有变量,那么就不需要构造方法对对象进行初始化,所以接口中也就没有构造方法。
成员方法:默认修饰符:public abstract ,说明接口中的方法都是抽象方法,所以在子类中实现接口时要么子类是抽象的,要么对接口中的所有方法进行重写。一般都是对方法进行重写。接口中的方法是抽象的,所以不能有方法体,以分号结束。如果子类中只需要用到接口中的某一个功能,那么就对其他功能写为空方法,即方法体是空的。因为成员方法默认是public的,可以省略不写,但是在子类中如果省掉了就是默认的修饰符:(友好的),访问权限低于接口中的public,而在方法重写中,子类方法的访问权限不能低于父类的访问权限,所以会报错。
接口实例化:接口因为是抽象的,所以不能实例化,也没有构造方法。但是抽象类有构造方法,因为子类继承创建对象时需要对父类进行初始化。
接口与类:
接口的多实现:用逗号隔开
class A extends Fu implements B,C{}
接口与接口之间是继承的关系。
类与类之间是继承的关系。(单继承,一个类只能继承一个类,但是父类可以继承祖先类)
返回值问题:
class Demo5
{
public static void main(String[] args)
{
FaPaiJi p = new FaPaiJi();
Card c = (Card)p.getPai();//Pai a = p.getPai()返回的是Pai类型,所以用Pai类型对象来接收,即父类引用指向子类对象(多态),此时a不能调用子类特有的方法(不能调用a.zha())。要想调用子类特有方法,需要强转为子类对象:即Card c = (Card)p.getPai();
c.zha();//强转为子类对象后,调用子类特有对象。
Magic m = p.getMagic();//返回值类型是接口,但返回的是该接口子类对象。(多态)
m.readHeart();//父类引用指向子类对象,编译看父类(接口),运行看子类
}
}
//返回值问题
/*
发牌机 发 牌
*/
class FaPaiJi
{
//返回值类型是类:返回的是该类的对象,子类对象(多态)
//返回值类型是抽象类:返回的是该抽象类的子类对象(多态)
//返回值类型是接口:返回的是该接口的子类对象(多态)
public Pai getPai(){
return new Card();//返回值类型是Pai类(抽象类),但返回的是Card对象(子类对象)
}
public Magic getMagic(){//返回值类型是接口,但返回的是该接口子类对象。
return new Card();
}
}
abstract class Pai
{
public abstract void win();
}
class MaJiang extends Pai
{
public void win(){
System.out.println("胡了 赢钱啦");
}
}
interface Magic
{
public void readHeart();
}
class Card extends Pai implements Magic
{
public void zha(){
System.out.println("4个2 炸");
}
public void win(){
System.out.println("炸完了,赢啦");
}
public void readHeart(){
System.out.println("读心术");
}
}
形参问题:
基本数据类型:传递的是值
public static void main(String[] args)
{
int i = 12,j = 23;
System.out.println(sum(i,j));//把i和j的值传给a和b,a和b再做什么运算就与i和j无关了
System.out.println(i+" "+j);//虽然上一步已经调用了sum函数了,在函数里a++,b++了,但是她操作的是传进去的12和23,而不是i和j,所以此处输出i和j=还是原来的数。
}
public static int sum(int a,int b){
a++;//对传进来的第一个参数值12进行++
b++;//对传进来的第二个参数值23进行++
return a+b;
}
引用数据类型:传递的是地址,实参和形参指向堆内存的同一个对象。
class Lianxi3
{
public static void main(String[] args)
{
Person ren = new Person();
//Pai zhipai = newPai();//Lianxi3.java:6: 错误: Pai是抽象的; 无法实例化。所以当参数类型是抽象类时,传递的实参应该是子类的对象,即父类的形参,子类对象是实参(多态创建对象)
Card zhipai = new Card();
ren.play(zhipai);
MaJiang m = new MaJiang();
ren.play(m);
System.out.println("***********");
Ma m1 = new Ma();
ren.money(m1);//当参数类型是类时,传入的实参可以是该类的对象。也可以是子类的对象。
ren.money(m);
System.out.println("***********");
ren.cool(zhipai);
}
}
class Person
{
public void play(Pai p){//当参数的类型是抽象类:传递的实参应该是该类的子类对象(多态)
p.win();
}
public void money(MaJiang m){//当参数类型是类时,传入的实参可以是该类的对象。也可以是子类的对象。
m.win();
}
public void cool(Magic c){//当参数是接口时,传入的形参是子类的对象(多态)
c.read();
}
}
interface Magic
{
public abstract void read();
}
abstract class Pai
{
public abstract void win();
}
class Card extendsPai implements Magic
{
public void read(){
System.out.println("读心术");
}
public void win(){
System.out.println("牌出完了");
}
}
class MaJiangextends Pai
{
public void win(){
System.out.println("糊了");
}
}
class Ma extendsMaJiang
{
public void ying(){
System.out.println("########");
}
}