Java复习打卡day26
开闭原则Open Closed Principle
概念
1. 开闭原则
开闭原则简单的理解就是多扩展少修改。
我们在编一段代码的时候可能扥代码都写完了,才发现有一段代码少了一项功能,那么这个是后我们会有两个选择,要么
将原来那个功能代码块修改一下,要么另外增加一个缺少的功能。先看第一个方案,由于这段代码在后面的程序中可能会有用到,
贸然将它修改的话后面的代码可能会出现崩溃,所以不可取,那么就只能用第二种方案了。第二种方案不但增添了缺失的功能,
而且还没有出现干扰到其他代码的问题。可见扩展代码的好处。
下面我将通过案例给大家展示。
案例演示
public interface IBook {
//接口,提供获得各项属性的方法
String getName();
int getPrice();
String getAuthorName();
}
public class Book implements IBook{
private String name;
private int price;
private String authorName;
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", authorName='" + authorName + '\'' +
'}';
}
public Book(){}
public Book(String name, int price, String authorName) {
this.name = name;
this.price = price;
this.authorName = authorName;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getPrice() {
return this.price;
}
@Override
public String getAuthorName() {
return this.authorName;
}
}
public class Reader {
//读者方法,将书本读出来
void readBook(Book b){
System.out.println("正在读书....");
System.out.println("正在读" + b.getAuthorName() + "的" + b.getName() + ",价格是" + b.getPrice()/100 + "¥。");
}
}
public class Test {
//创建书对象,并测试
static {
new Reader().readBook(new SaleBook("《红楼梦》",9700,"曹雪芹"));
new Reader().readBook(new SaleBook("《西游记》",8700,"吴承恩"));
new Reader().readBook(new SaleBook("《水浒传》",10700,"施耐庵"));
new Reader().readBook(new SaleBook("《三国演义》",5700,"罗贯中"));
}
public static void main(String[] args) {
//没有任何问题,但是此时要促销:
//当书的价格高于70时,打八折;
//当书的价格高于90时打七折。
}
}
//当出现了要大促销的时候,下面的方法实现了书价格的打折
public class SaleBook extends Book{
//促销书
public SaleBook(String name, int price, String authorName) {
super(name, price, authorName);
}
@Override
public int getPrice(){
int sellPrice = super.getPrice()/100;
int offPrice = 0;
if(sellPrice>=90){
offPrice = (sellPrice * 70) / 100;
}else if(sellPrice>=70){
offPrice = (sellPrice * 80) / 100;
}else{
offPrice = sellPrice;
}
return (offPrice * 100);
}
}
单一职责原则Single Responsibility Principle
概念
2.单一职责原则
单一职责原则没有案例来解释,我将完全通过口述向大家讲解。
就是一个类实现一项功能,或者一个接口实现一个功能。
e.g.:
public interface Expressor{
//快递员接口
//快递员职能:1.增加快递;
//2.删除快递;
//3.查找快递。
void add();
void delete();
void find();
}
这三个快递操作方法,就是三个功能所以这一个接口就实现了三个功能,这样的话,当随便一个功能需要改进或者弃用的话,
都会对这个接口产生影响,所以可以将这个接口的三个方法,分别继承到三个子类中,这样不但增加了代码抗耦合性,还增加了代
码的复用性,这就是单一职责原则。
在这里,提一句,在开发界经常会有人因为这一原则发生争吵,为什么呢,应为这个原则因人而异,因代码而异,所以可能
会产生很多不同的意见,大家在日后的编程中要变通一点。原则是死的,人是活的,根据实际情况来。
里氏替换原则Liskov Substitution Principle
概念
含义
//先创建一个Gun接口,并产生一个抽象方法。
public interface Gun {
//枪可以射击
void shoot();
//这里的shoot方法捡回被这个借口的所有子类实现
//这体现了里氏替换原则的第一个含义!
}
//创建一个测试的类
public class Test {
public static void main(String[] args) {
//士兵杀敌
new Solider().killEnemy(new Rifle());
new Snipper().killEnemy(new Gup());
}
}
//在创建一个手枪的类
public class HandGun implements Gun {
@Override
public void shoot() {
System.out.println("手枪射击");
}
}
//创建一个步枪的类
public class Rifle implements Gun {
@Override
public void shoot() {
System.out.println("步枪射击");
}
}
//创建一个机枪的类
public class MachineGun implements Gun {
@Override
public void shoot() {
System.out.println("机枪射击");
}
}
//这里创建了一个Gup枪的类
public class Gup extends Rifle {
//Gup可以使用望远镜先观察,确保安全后,在瞄准杀敌。
public void snip(){
System.out.println("使用望远镜观察环境---");
}
//这就是子类比父类多出来的方法
//它体现了里氏替换原则的第二个含义!
@Override
public void shoot() {
System.out.println("Gup射击");
}
}
//创建了一个狙击手的类
public class Snipper extends Solider{
//这是一个使用Gup的特种兵
void killEnemy(Gup g) {
//这是方法的重载
g.snip();
g.shoot();
System.out.println("士兵杀敌!");
}
}
下面是父子继承的案例代码,主要体现了里氏替换原则的后两个含义。
import java.util.HashMap;
import java.util.Map;
public class Demo {
class Parent{
public void lsp1(Map hashMap){
System.out.println("父类执行了-------");
}
}
class Sub extends Parent{
public void lsp1(HashMap hashMap) {
System.out.println("子类执行了");
}
}
public static void main(String[] args) {
Demo lsp = new Demo();
Parent p = lsp.new Parent();
p.lsp1(new HashMap());
Sub s = lsp.new Sub();
s.lsp1(new HashMap());
//当子类传入的参数比父类大的时候,代码会自动执行父类的代码
//当子类传入的参数不比父类大时候,就会执行子类的代码了。
//这里体现了里氏替换原则的含义三!
}
}
//---------------------------------------------------------
import java.util.HashMap;
import java.util.Map;
public class Demo1 {
abstract class Parent{
public abstract Map lsp1();
}
class Sub extends Parent{
@Override
public HashMap lsp1() {
return new HashMap();
}
}
//这里面体现了里氏替换原则的含义四
public static void main(String[] args) {
Demo1 lsp = new Demo1();
}
}