Java语言基础(7)面向对象 | 您所在的位置:网站首页 › java实现接口的类不能是抽象类 › Java语言基础(7)面向对象 |
面向对象
3.1、 抽象类3.1.1、采用abstract声明抽象类3.1.2、抽象的方法只需在抽象类中,提供声明,不需要实现,起到了一个强制的约束作用,要求子类必须实现3.1.3、如果这个类是抽象的,那么这个类被子类继承,抽象方法必须被覆盖。如果在子类中不覆盖该抽象方法,那么必须将此方法再次声明为抽象方法3.1.4、抽象类不能被final修饰3.1.5、抽象方法不能被final修饰3.1.6、抽象类中可以没有抽象方法(参见3.1.1)
4.1、 接口(行为)4.1.1、接口中的方法默认都是public abstract的,不能更改4.1.2、接口中的变量是public static final类型的,不能更改,所以必须显示的初始化4.1.3、接口不能被实例化,接口中没有构造函数的概念4.1.4、接口之间可以[多]继承,但接口之间不能实现4.1.5、如果一个类实现了接口,那么接口中所有的方法必须实现4.1.6、一类可以实现多个接口4.1.7、一个接口可以继承多个接口4.1.8、 接口的进一步应用
接口和抽象类的区别?
3.1、 抽象类
看我们以前示例中的Person、Student和Employee,从我们使用的角度来看主要对Student和Employee进行实例化,Person中主要包含了一些公共的属性和方法,而Person我们通常不会实例化,所以我们可以把它定义成抽象的: ● 在java中采用abstract关键字定义的类就是抽象类,采用abstract关键字定义的方法就是抽象方法 ● 抽象的方法只需在抽象类中,提供声明,不需要实现 ● 如果一个类中含有抽象方法,那么这个类必须定义成抽象类 ● 如果这个类是抽象的,那么这个类被子类继承,抽象方法必须被重写。如果在子类中不复写该抽象方法,那么必须将此类再次声明为抽象类 ● 抽象的类是不能实例化的,就像现实世界中人其实是抽象的,张三、李四才是具体的 ● 抽象类不能被final修饰(它是需要被继承的) ● 抽象方法不能被final修饰,因为抽象方法就是被子类实现的 抽象类中可以包含方法实现,可以将一些公共的代码放到抽象类中,另外在抽象类中可以定义一些抽象的方法,这样就会存在一个约束,而子类必须实现我们定义的方法,如:teacher必须实现printInfo方法,Student也必须实现printInfo方法,方法名称不能修改,必须为printInfo,这样就能实现多态的机制,有了多态的机制,我们在运行期就可以动态的调用子类的方法。所以在运行期可以灵活的互换实现。 接口我们可以看作是抽象类的一种特殊情况,在接口中只能定义抽象的方法和常量 在java中接口采用interface声明接口中的方法默认都是public abstract的,不能更改接口中的变量默认都是public static final类型的,不能更改,所以必须显示的初始化接口不能被实例化,接口中没有构造函数的概念接口之间可以继承,但接口之间不能实现接口中的方法只能通过类来实现,通过implements关键字如果一个类实现了接口,那么接口中所有的方法必须实现一类可以实现多个接口接口可以继承多个接口 4.1.1、接口中的方法默认都是public abstract的,不能更改 public class InterfaceTest01 { public static void main(String[] args) { } } //采用interface定义接口 //定义功能,没有实现 //实现委托给类实现 interface StudentManager { //正确,默认public abstract 等同public abstract void addStudent(int id, String name); public void addStudent(int id, String name); //正确 //public abstract void addStudent(int id, String name); //正确,可以加入public修饰符,此种写法较多 public void delStudent(int id); //正确,可以加入abstract,这种写法比较少 public abstract void modifyStudent(int id, String name); //编译错误,因为接口就是让其他人实现 //采用private就和接口原本的定义产生矛盾了 private String findStudentById(int id); } 4.1.2、接口中的变量是public static final类型的,不能更改,所以必须显示的初始化 public class InterfaceTest02 { public static void main(String[] args) { //不能修改,因为final的 //StudentManager.YES = "abc"; System.out.println(StudentManager.YES); } } interface StudentManager { //正确,默认加入public static final String YES = "yes"; //正确, 开发中一般就按照下面的方式进行声明 public static final String NO = "no"; //错误,必须赋值,因为是final的 //int ON; //错误,不能采用private声明 private static final int OFF = -1; } 4.1.3、接口不能被实例化,接口中没有构造函数的概念 public class InterfaceTest03 { public static void main(String[] args) { //接口是抽象类的一种特例,只能定义方法和变量,没有实现 //所以不能实例化 StudentManager studentManager = new StudentManager(); } } interface StudentManager { public void addStudent(int id, String name); } 4.1.4、接口之间可以[多]继承,但接口之间不能实现 public class InterfaceTest04 { public static void main(String[] args) { } } interface inter1 { public void method1(); public void method2(); } interface inter2 { public void method3(); } //接口可以继承 interface inter3 extends inter1 { public void method4(); } //接口不能实现接口 //接口只能被类实现 interface inter4 implements inter2 { public void method3(); } 4.1.5、如果一个类实现了接口,那么接口中所有的方法必须实现 public class InterfaceTest05 { public static void main(String[] args) { //Iter1Impl实现了Inter1接口 //所以它是Inter1类型的产品 //所以可以赋值 Inter1 iter1 = new Iter1Impl(); iter1.method1(); //Iter1Impl123实现了Inter1接口 //所以它是Inter1类型的产品 //所以可以赋值 iter1 = new Iter1Impl123(); iter1.method1(); //可以直接采用Iter1Impl来声明类型 //这种方式存在问题 //不利于互换,因为面向具体编程了 Iter1Impl iter1Impl = new Iter1Impl(); iter1Impl.method1(); //不能直接赋值给iter1Impl //因为Iter1Impl123不是Iter1Impl类型 //iter1Impl = new Iter1Impl123(); //iter1Impl.method1(); } } //接口中的方法必须全部实现 class Iter1Impl implements Inter1 { public void method1() { System.out.println("method1"); } public void method2() { System.out.println("method2"); } public void method3() { System.out.println("method3"); } } class Iter1Impl123 implements Inter1 { public void method1() { System.out.println("method1_123"); } public void method2() { System.out.println("method2_123"); } public void method3() { System.out.println("method3_123"); } } abstract class Iter1Impl456 implements Inter1 { public void method1() { System.out.println("method1_123"); } public void method2() { System.out.println("method2_123"); } //再次声明成抽象方法 public abstract void method3(); } //定义接口 interface Inter1 { public void method1(); public void method2(); public void method3(); } 4.1.6、一类可以实现多个接口public class InterfaceTest06 { public static void main(String[] args) { //可以采用Inter1定义 Inter1 inter1 = new InterImpl(); inter1.method1(); //可以采用Inter2定义 Inter2 inter2 = new InterImpl(); inter2.method2(); //可以采用Inter3定义 Inter3 inter3 = new InterImpl(); inter3.method3(); }} //实现多个接口,采用逗号隔开 //这样这个类就拥有了多种类型 //等同于现实中的多继承 //所以采用java中的接口可以实现多继承 //把接口粒度划分细了,主要使功能定义的含义更明确 //可以采用一个大的接口定义所有功能,替代多个小的接口, //但这样定义功能不明确,粒度太粗了 class InterImpl implements Inter1, Inter2, Inter3 { public void method1() { System.out.println("----method1-------"); } public void method2() { System.out.println("----method2-------"); } public void method3() { System.out.println("----method3-------"); }} interface Inter1 { public void method1();} interface Inter2 { public void method2();} interface Inter3 { public void method3();} /* interface Inter { public void method1(); public void method2(); public void method3();} */ 4.1.7、一个接口可以继承多个接口 //声明接口:interface interface A{ public static final int CONST = 1; void a();//接口中的方法默认都是public abstract的 } interface K{ void k(); } //接口可以继承多个接口 interface B extends A,K{ void b(); int d(); } 4.1.8、 接口的进一步应用在java中接口其实描述了类需要做的事情,类要遵循接口的定义来做事,使用接口到底有什么本质的好处?可以归纳为两点:(提供了标准、规范) ● 采用接口明确的声明了它所能提供的服务 ● 解决了Java单继承的问题(一个类可以实现多个接口,一个接口可以继承多个接口) ● 实现了可接插性(重要) 示例:完成学生信息的增删改操作,系统要求适用于多个数据库,如:适用于Oracle和MySQL; 第一种方案,不使用接口,每个数据库实现一个类: 需求发生变化了,客户需要将数据移植Mysql上 Mysql的实现 public class StudentMysqlImpl { public void addStudent(int id, String name) { System.out.println("StudentMysqlImpl.addStudent()"); } public void deleteStudent(int id) { System.out.println("StudentMysqlImpl.deleteStudent()"); } public void udpateStudent(int id, String name) { System.out.println("StudentMysqlImpl.udpateStudent()"); } }调用以上两个类完成向Oracle数据库和Mysql数据存储数据 public class StudentManager { public static void main(String[] args) { //对Oracle数据库的支持 /* StudentOracleImpl studentOracleImpl = new StudentOracleImpl(); studentOracleImpl.add(1, "张三"); studentOracleImpl.del(1); studentOracleImpl.modify(1, "张三"); */ //需要支持Mysql数据库 StudentMysqlImpl studentMysqlImpl = new StudentMysqlImpl(); studentMysqlImpl.addStudent(1, "张三"); studentMysqlImpl.deleteStudent(1); studentMysqlImpl.udpateStudent(1, "张三"); } }以上代码不能灵活的适应需求,当需求发生改变需要改动的代码量太大,这样可能会导致代码的冗余,另外可能会导致项目的失败,为什么会导致这个问题,在开发中没有考虑到程序的扩展性,就是一味的实现,这样做程序是不行的,所以大的项目比较追求程序扩展性,有了扩展性才可以更好的适应需求。 第二种方案,使用接口 UML,统一建模语言 |
CopyRight 2018-2019 实验室设备网 版权所有 |