在程序设计的时候一定要注重“思考”和“实现”两个过程,这是两个阶段,先思考再去实现,可以让思路更加的清晰,开发起来更有条理,列举出有哪几个模块哪几个方法(传什么给你,返回给我什么), 接口与抽象类是面向对象思想的两个重要概念。接口仅是方法定义和常量值定义的集合,方法没有函数体;抽象类定义的内容理论上比接口中的内容要多得多,可定义普通类所包含的所有内容,还可定义抽象方法,这也正是叫作抽象类的原因所在。接口、抽象类本身不能示例化,必须在相应子类中实现抽象方法,才能获得应用。 那么,如何更好地理解接口与抽象类?接口中能定义抽象方法,为什么还要抽象类?抽象方法无函数体,不能示例化,说明接口、抽象类本身没有用途,这种定义有意义吗?接口与抽象类的关系到底如何? 获得这些问题答案的最好办法就是来自于生活实践。例如写作文的时候,一定要先思考好先写什么,后写什么;做几何题的时候,要想清楚如何引辅助线,用到哪些公理、定理等;做科研工作的时候,一定要思索哪些关键问题必须解决;工厂生产产品前,必须制订完善的生产计划等。也就是说,人们在做任何事情前,一般来说是先想好,再去实现。这种模式在生活中是司空见惯的。因此,Java语言一定要反映“思考-实现”这一过程,通过不同关键字来实现,即用接口(interface)、抽象类(abstract)来反映思考阶段,用子类(class)来反映实现阶段。 从上文易于得出:“思考-实现”是接口、抽象类的简单语义。从此观点出发,结合生活实际,可以方便回答许多待解答的问题,具体如下。 为什么接口、抽象类不能示例化?由于接口、抽象类是思考的结果,只是提出了哪些问题需要解决,无需函数体具体内容,当然不能示例化了。 为什么接口、抽象类必须由子类实现?提出问题之后,总得有解决的方法。Java语言是通过子类来实现的,当然一定要解决“思考”过程中提出的所有问题。 接口、抽象类有什么区别?可以这样考虑,人类经思考后提出的问题一般有两类:一类是“顺序”问题,另一类是“顺序+共享”问题。前者是用接口描述的,后者是用抽象类来描述的。
首先来了解一下类之间的关系有哪一些:继承(泛化),实现,依赖,关联。。。 1:单一职责原则:一个类尽可能让他只负责一件事,说白了就是不要把太多的东西写在一个类上 2:接口隔离原则:说白了就是不要让一个接口写太多的方法,实现的类多了和调用这个接口的类多了就会增加类之间的耦合度 3:依赖倒转原则:抽象不应该依赖细节,细节应该依赖于抽象,核心思想就面向接口编程,尽可能把细节交给听他们的实现类去完成 4:里氏变换原则:让引用的基类可以透明的知道和调用他们的子类的的方法,尽量避免重写父类已经实现的方法,这样子会造成很大的耦合度,对程序的改变是很大 5:开闭原则:是最重要的的原则,是为了实现程序模块的可扩展性,把用抽象构建框架,抽象成一个抽象类,当要扩展的时候让子类来继承这个抽象类就行了,对于调用者来说就是可扩展的, 6:迪米特原则:也叫最叫做最少知道原则,不是自己直接朋友的事情最好不要知道,也不要去调用,让自己的直接朋友去处理 7:合成复用原则:尽量用合成/聚合的方式而不是使用继承
abstract的方法没有方法体,abstract的类没有实例对象 接口可以说是抽象类的一种特列::(接口是只能含有public abstract方法,和public final static的常量的的抽象类)。。。 接口所有方法都是abstract,public,但是方法不能是static的,所有的成员变量都是public static,final的 抽象类体现的是一个共享的原则,它可以有普通成员的变量,有些方法可以有方法体,可以有静态方法,抽象方法前面必须加abstract;接口是默认的,不用加。 两者在语法上的具体区别: 1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
抽象类中可以包含静态方法,接口中不能包含静态方法
抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
一个类可以实现多个接口,但只能继承一个抽象类。
注意点1:依赖是最广泛的关系:比如说A类调用了接口B,C类实现了接口B,那么A和C就是存在依赖关系; 注意点2:聚合和组合的关系,一个是否共存亡的区别;聚合不共存亡,组合共存亡;
看看尚硅谷文档的解析:关键看下面的代码举例::::
自动装配干的事情就是帮我们去new 一个实现类(可以是接口的实现类或者是抽象类的实现类),比如说是@Autowired或者@Resource都是加在一个接口上的,用来“发起”自动装配这个动作,程序员不用去new。@Controller,@Service,@Component和@Resposity是加在实现类上面的,用来表示可以被加载,启动的时候会被加载到容器上,当有多个实现类实现了同一个接口时,就用@Resource,应为他时按名字来注入的;例如:1.@Service(“atest”),2.@Service(“test01”)两个接口都实现了同一个接口: 在声明这个接口的时候就要用:@Resouce:,名字和Service上的一样就回去调用这个name相同的实现类; @Autowired 是通过 byType 的方式去注入的, 使用该注解,要求接口只能有一个实现类。 2、@Resource 可以通过 byName 和 byType的方式注入, 默认先按 byName的方式进行匹配,如果匹配不到,再按 byType的方式进行匹配。 3、@Qualifier 注解可以按名称注入, 但是注意是 类名。
@Service()
此注注解属于业务逻辑层,service或者manager层 默认按照名称进行装配,如果名称可以通过name属性指定,如果没有name属性,注解写在字段上时,默认去字段名进行查找,如果注解写在setter方法上,默认按照方法属性名称进行装配。当找不到匹配的bean时,才按照类型进行装配,如果name名称一旦指定就会按照名称进行装配
public class testinterface { @Resource(name = "test01") interface01 tt; @Test public void test(){ /* for (interface01 t:tt) System.out.println(t.test2Injection());*/ System.out.println( tt.test2Injection()); } }而在平时的写main函数的时候没有没有框架帮我们完成,只是声明了一个接口或者一个抽象类,当调用他们的方法时就会报空指针异常,找不到,这是因为还没有装配的java堆里面,找不到。。。看下面的main函数例子:
public final class main { /*private AbstractClass abstractClass =new AbstractClass() { @Override public String abstractFunction() { return null; } };*/ /*=new myinterface() { @Override public String interfaceFuction() { return null; } };*/ /*main的class外面的成员和方法必须是static; 接口和抽象类的声明只是一个静态类型,new后面的是实际类型,后面必须是自己的实现类, 否则调用抽象类和接口的方法时会报空指针,即使调用的是抽象类的普通方法 * */ static myinterface myinterface01 =new shixianlei(); static AbstractClass abstractClass01=new shixianlei(); private String string; public static void main(String[] strings){ DiaoyongClass diaoyongClass ;//=new DiaoyongClass(); AbstractClass abstractClass02=new AbstractClass() { /*如果后面new的不是实现类而是new自身的抽象类或者接口的话 可以用这种方式来实现,在new完之后加一个{} * */ @Override public String abstractFunction() { System.out.println("抽象类的抽象方法+++02"); return null; } }; myinterface myinterface02=new myinterface() { @Override public String interfaceFuction() { return null; } }; abstractClass02.abstractFunction(); System.out.println(); // System.out.println(inname.interfaceFuction());空指针 // diaoyongClass.call(); myinterface01.interfaceFuction(); // abstractClass.abstractFunction(); abstractClass01.putongFuntion(); AbstractClass.staticFunction(); } }输出:
抽象类的抽象方法+++02
实现接口 抽象类普通方法 抽象类的静态方法