面向接口编程
抽象类和抽象方法
关键词:abstract
抽象类
父类引用变量指向子类对象,普通方法调用子类重写方法。
静态方法,成员变量调用时是静态绑定和变量类型相关
public abstract class Base {
public abstract void meathod1();
public void method2(){}
public static void meathod4(){
System.out.println("父类meathod4");
}
String a="Base";
}
public class sub1 extends Base {
public String a="sub1";
public void meathod1(){
System.out.println("子类meathod1");
}
public static void meathod4(){
System.out.println("子类meathod4");
}
}
public class Test {
public static void main(String[] args) {
Base base=new sub1();
System.out.println(base.a);
base.meathod1();
base.meathod4();
}
}
运行结果:
Base
子类meathod1
父类meathod4
为什么使用接口
接口关键字:interface,接口里的方法默认都是抽象方法不用写abstract
public interface MyInterface{
//变量:public static final
//变量方发:public abstract
}
实现类:public class Myclass implements extends Base MyInterFace,Minterface2{
}
public interface UsbInterface {
//USB提供服务
void service();
}
/*实现类*/
public class UDisk implements UsbInterface {
public void service(){
System.out.println("向电脑传输数据");
}
}
public class Test {
public static void main(String[] args) {
UsbInterface udisk=new UDisk();
udisk.service();
}
}
继承关系:is a 的关系(防盗门是一个门)
接口关系:has a 的关系(防盗门有一个锁)
上锁和开锁是锁的能力
实线箭头:继承一个类
虚线箭头:实现接口
手机父类
package Phone;
public abstract class Phone {
private String brand;
private String type;
public abstract void sendInfo();
public abstract void call();
public void info(){
System.out.println("这是一款型号为"+this.getType()+"的"+this.getBrand()+"手机:");
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
智能手机类
package Phone;
public abstract class Phone {
private String brand;
private String type;
public abstract void sendInfo();
public abstract void call();
public void info(){
System.out.println("这是一款型号为"+this.getType()+"的"+this.getBrand()+"手机:");
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
普通手机类
package Phone;
public class CommonPhone extends Phone implements PlayWiring {
public void play(){
System.out.println("开播放音乐《热血》");
}
public void sendInfo(){
System.out.println("发送文字信息");
}
public void call(){
System.out.println("开始语音通话");
}
}
网络接口
package Phone;
public interface Network {
void networkConn();
}
拍照接口
package Phone;
public interface TheakePictures {
void takePicture();
}
j
播放接口
package Phone;
public interface PlayWiring {
void play();
}
测试类
package Phone;
public class Test {
public static void main(String[] args) {
SmartPhone smartPhone=new SmartPhone();
smartPhone.setBrand("Xiaomi");
smartPhone.setType("14POR");
smartPhone.info();
smartPhone.networkConn();
smartPhone.play();
smartPhone.takePicture();
smartPhone.sendInfo();
smartPhone.call();
CommonPhone commonPhone=new CommonPhone();
commonPhone.setBrand("索尼爱立信");
commonPhone.setType("G502c");
commonPhone.info();
commonPhone.play();
commonPhone.sendInfo();
commonPhone.call();
}
}
墨盒接口
package Print;
/*墨盒*/
public interface InkBox {
String getColor();
}
纸张接口
package Print;
public interface Paper {
String getSize();
}
黑白墨盒(实现墨盒接口)
package Print;
public class GrayInlBox implements InkBox {
public String getColor(){
return "黑白";
}
}
彩色墨盒(实现墨盒接口)
package Print;
public class ColorInkBox implements InkBox {
public String getColor(){
return "彩色";
}
}
A4纸张(实现纸张接口)
package Print;
public class A4paper implements Paper {
public String getSize(){
return "A4";
B5纸张(实现纸张接口)
package Print;
public class B5paper implements Paper {
public String getSize(){
return "B5";
}
}
打印机类
package Print;
public class Print {
InkBox inkBox;
Paper paper;/**使用两个接口的类型作为Print的成员变量 **/
public void setInkBox(InkBox inkBox) {
this.inkBox = inkBox;
}
public InkBox getInkBox() {
return inkBox;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public Paper getPaper() {
return paper;
}
public void printinfo(){
System.out.println("正在使用"+inkBox.getColor()+"墨盒"+"在"+paper.getSize()+"打印");
}
}
测试类
package Print;
public class Test {
public static void main(String[] args) {
Print print=new Print();
InkBox inkBox =new GrayInlBox();//接口类型
Paper paper=new A4paper();//接口类型
print.setInkBox(inkBox);
print.setPaper(paper);
print.printinfo();
}
}
遇到的问题
在Test类中通过
InkBox inkBox =new GrayInlBox();//接口类型
Paper paper=new A4paper();//接口类型
创建了inBox:类型为inkBox实际类型是GrayInlBox
创建了paper:类型为Paper实际类型是A4paper
将这两个参数传给print的setInkBox和setPaper方法
由于Java虚拟机动态绑定机制当print类中的printnfo方法使用inkBox.getColor()和paper.getSize()调用的是A4paper类中的getSize()方法和GrayInlBox类中的getColor()方法
Print
类有两个方法 setInkBox
和 setPaper
,它们接受 InkBox
和 Paper
类型的参数。当您创建 GrayInlBox
和 A4paper
的实例,并将它们传递给 Print
类的 setInkBox
和 setPaper
方法时,JVM 会动态绑定这些实例的方法。
这意味着,尽管 inkBox
和 paper
在 Print
类中被声明为 InkBox
和 Paper
类型,但它们的实际类型是 GrayInlBox
和 A4paper
。因此,当 Print
类的 printinfo
方法调用 inkBox.getColor()
和 paper.getSize()
时,JVM 会确保调用的是 GrayInlBox
和 A4paper
类中实现的这些方法,而不是 InkBox
和 Paper
接口中的方法。
在 Java 中,当您创建一个类的实例时,比如 GrayInlBox
或 A4paper
,您实际上是在创建一个符合其对应接口(InkBox
或 Paper
)契约的对象。这意味着 GrayInlBox
和 A4paper
类必须实现 InkBox
和 Paper
接口的所有方法。
由于 InkBox
接口有一个 getColor()
方法,而 GrayInlBox
类实现了这个方法并返回 “黑白”,所以当您创建 GrayInlBox
的实例时,您知道这个实例有一个 getColor()
方法,它将返回 “黑白”。
同样地,由于 Paper
接口有一个 getSize()
方法,而 A4paper
类实现了这个方法并返回 “A4”,所以当您创建 A4paper
的实例时,您知道这个实例有一个 getSize()
方法,它将返回 “A4”。
在 Test
类中,当您执行以下代码时:
InkBox inkBox = new GrayInlBox(); // 接口类型
Paper paper = new A4paper(); // 接口类型
您实际上是在创建 GrayInlBox
和 A4paper
的实例,并将这些实例赋值给 InkBox
和 Paper
类型的变量 inkBox
和 paper
。
(类似于父类引用变量指向子类对象)
由于 GrayInlBox
和 A4paper
分别实现了 InkBox
和 Paper
接口,所以 inkBox
和 paper
变量将具有这些接口定义的所有方法。
然后,当您执行以下代码时:
print.setInkBox(inkBox);
print.setPaper(paper);
您将 inkBox
和 paper
对象传递给 Print
类的 setInkBox
和 setPaper
方法。这样,Print
类就可以使用这些对象来调用它们的 getColor()
和 getSize()
方法,以获取墨盒的颜色和纸张的大小。
最后,在 Print
类的 printinfo
方法中,通过以下代码获取墨盒的颜色和纸张的大小,并打印出来:
System.out.println("正在使用" + inkBox.getColor() + "墨盒" + "在" + paper.getSize() + "打印");
和 Paper
接口,所以 inkBox
和 paper
变量将具有这些接口定义的所有方法。
然后,当您执行以下代码时:
print.setInkBox(inkBox);
print.setPaper(paper);
您将 inkBox
和 paper
对象传递给 Print
类的 setInkBox
和 setPaper
方法。这样,Print
类就可以使用这些对象来调用它们的 getColor()
和 getSize()
方法,以获取墨盒的颜色和纸张的大小。
最后,在 Print
类的 printinfo
方法中,通过以下代码获取墨盒的颜色和纸张的大小,并打印出来:
System.out.println("正在使用" + inkBox.getColor() + "墨盒" + "在" + paper.getSize() + "打印");
这就是您如何知道 inkBox
和 paper
的值的方式。通过实现接口并创建对应类的实例,您可以确保这些实例具有接口定义的方法,并且可以安全地在 Print
类中使用这些方法。