当前位置: 首页 > 后端技术 > Java

面向对象与设计原则

时间:2023-04-02 09:19:35 Java

类抽象类与接口的三大特性抽象类(abstract)的三大特性接口(interface)的三大特性抽象类与接口的区别封装SOLID原理的三大特性:封装也称为信息隐藏或数据访问保护。通过暴露有限的访问接口,外界只能被授权以有限的方式访问内部信息或数据。在Java语言中,主要是通过public、protected、private等关键字来实现的。继承:用来表示类之前的is-a关系,比如猫是哺乳动物。从继承关系上来说,继承可以分为单继承和多继承。多重遗传意味着,例如,猫可以是哺乳动物或爬行动物。继承最大的好处就是可以实现代码复用,也就是你可以把所有子类都有的属性或者方法提取到父类中。多态性:子类可以替代父类,比如Mapmap=newHashMap(),多态性提高了代码的扩展性和复用性。如下,whatyousay方法会根据传入的不同对象输出不兼容的内容。interfaceProgrammingLanguage{publicvoidsay();}classJavaLanguageimplementsProgrammingLanguage{publicvoidsay(){System.out.println("java是最好的网络语言");};}classPhpLanguageimplementsProgrammingLanguage{publicvoidsay(){System.out.println("php是最好的网络语言");};}publicclassDemo{publicvoidwhatyousay(ProgrammingLanguagelanguage){language.say();}publicstaticvoidmain(String[]args){ProgrammingLanguagelan=newJavaLanguage();说(局域网);}}抽象类和接口的三个特点抽象类的一个对象。抽象类中有两种属性和方法。抽象属性和方法:只声明,不实现非抽象属性和方法:声明+实现子类实现抽象方法:子类必须实现父类中的所有抽象方法。接口(interface)的三个属性接口不能包含属性接口只能声明方法,不能包含实现代码(java8后默认)类实现接口类时,必须实现接口中声明的所有方法的区别抽象类和接口之间抽象类是对成员变量和方法的抽象。是一个is-a关系,就是为了解决代码复用的问题。动物的特征。所谓动物特征,相当于抽象类中的抽象属性和方法。猫和狗都具有动物的特性,即实现动物的抽象属性接口只是解决方法的抽象(抽象类-类抽象),这是一种has-a关系,就是解决解耦问题和提高代码的可扩展性has-a:表示对象与其属性的从属关系同一类的对象通过其属性的不同值来区分,如:小明和小红都是一样的类(Person)但是他们有不同的属性值Personxiaoming=newXiaoming("Xiaoming")两者是整体和部分的关系然后区分抽象类——强调什么是B继承抽象类A并实现了A中的抽象属性和方法,那么它就属于A,比如一只鸟(有翅膀,尖嘴,会下蛋)-继承-B(会说话的人):B继承了鸟的抽象类那么他要实现鸟类的相关特征,所以它是鹦鹉界面——强调它的功能。Man和Woman实现了Person接口,重写了Person中的相关方法,但赋予的内容不同,因而具有不同的能力。总结一下,抽象类就是为了解决代码复用的问题。比如你要写所有与鸟有关的类,你就把每只鸟所具有的属性写在抽象类中,然后在子类中写不同鸟特有的。属性,这样你就不需要在子类中添加这些属性。让代码高度可复用接口是为了解决抽象问题。比如你要写王者荣耀中所有英雄的技能,假设这些英雄只有3个技能,那么我们在界面中定义(技能1,技能2,技能3)就可以了,然后每个英雄的技能都可以在子类中实现。接口意识、封装意识、抽象意识基于接口而不是实现编程接口意识,良好的抽象和封装可以提高代码的灵活性,更好地响应需求的变化。下面,我们实现一个RabbitMq收发消息的场景。首先,这显然是一种“看似面向对象,实则面向过程”的实现。代码没有被有效抽象。整个发布消息的过程其实就是一段代码另外,一旦需求发生变化,如果后期将RabbitMq换成其他消息队列,不仅RabbitMqPub类会被丢弃,而且还会面临大量的代码修改在使用RabbitMqPub的地方。publicclassRabbitMqPub{//用于创建到MQ的物理连接privatestaticConnectionFactoryfactory=newConnectionFactory();static{//设置地址、用户名、密码等工厂参数}privateConnectionconn;私人频道ch;//获取连接publicConnectiongetConnection(){if(connnect!=null)returnconn;否则返回factory.newConnection();}//获取频道publicChannelgetChannel(Connectionconn){if(ch!=null)returnch;否则返回conn.newChannel();}//发送消息publicvoidpublish(Channelch,Stringtopic,StringrouteKey,Stringmsg){......}//还有订阅、关闭连接等方法//......}publicclassPublishJob{RabbitMqPubpub=newRabbitMqPub();publicvoidpublishMsg(){连接conn=pub.getConnection();频道ch=pub.getChannel(conn);pub.publish(ch,......);}}下面是对上述代码的抽象封装,利用Spring的工厂和反射思想来配置MqPub。实现了多个消息队列的发布后,我们只需要在代码中配置相应的接口进行调用即可,不需要关心使用的是哪个消息队列,只需要在配置文件中进行修改即可切换消息队列。publicinterfaceMqPub{//...publicvoidpublish(Stringtopic,StringrouteKey,Stringmsg);}publicclassRabbitMqPubimplementsMqPub{//用于创建到MQ的物理连接privatestaticConnectionFactoryfactory=newConnectionFactory();static{//设置地址、用户名、密码等工厂参数}privateConnectionconn;私人频道ch;//获取连接privateConnectiongetConnection(){if(connnect!=null)returnconn;否则返回工厂.newConnection();}//获取频道privateChannelgetChannel(){if(ch!=null)returnch;否则返回getConnection().newChannel();}//发送消息publicvoidpublish(Stringtopic,StringrouteKey,Stringmsg){.....}//还有订阅、关闭连接等方法//...}publicclassPublishJob{MqPubpub=MqFactory.getMqPub();publicvoidpublishMsg(){pub.publish(...);}}publicClassMqFactory{privatefinalStringmqClassPath;静态{字符串类型=getProperties("XXXX");如果(“兔子”.equals(类型)){mqClassPath=getProperties("XXXX");}}publicstaticMqPubgetMqPub(){Classclz=Class.forName(mqClassPath)returnclz.newInstance();}}SOLID原则单一职责原则(SingleResponsibilityPrinciple):一个类或一个模块只负责完成一个职责开闭原则(OpenClosePrinciple):对扩展开放,对修改关闭,前者是为了满足新的需求,后者后者是为了保证系统的稳定性里氏替换原则(LiskovSubstitutionPrinciple):子类对象可以替换父类对象中出现的任何对象,保证原程序的逻辑行为保持不变且正确性没有改变。映射map=newHashMap();客户端使用,那么可以为每个客户端创建一个接口,然后这个类实现所有的接口,而不是只实现一个接口,里面包含了所有客户端使用的方法。/***Crawl**/interfaceCrawl{}/***Swimming**/interfaceSwimming{}/***Reptile**/类Reptile实现Crawl{}/***Amphibian**/类Amphibian实现Crawl,Swimming{}依赖倒置原则(DependenceInversionPrinciple):模块之间的依赖是通过抽象发生的,实现类之间没有直接的依赖关系。依赖关系是通过抽象类或接口生成的。/***Crawl**/interfaceCrawlAnimal{}/***Rabbit**/类RabbitimplementsCrawlAnimal{}/***Reptilerace**/classAnimalOfCrawlRun{SetcrawlAnimalSets=newHashSet();voidaddAnimal(CrawlAnimal动物){crawlAnimalSets.add(动物);}...}classClient{AnimalOfCrawlRunrun=newAnimalOfCrawlRun();publicvoidtest(){run.addAnimal(newRabbit());}}