经历了由面向过程到面向面向对象的转换,基本上已经可以写一个差不多的面向对象的程序出来了。众所周知,面向对象的三大要素:封装,继承,多态。这次先从这里说起:
以下引用于 知乎用户invalid s
一,封装:
封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项,或者叫接口。
有了封装,就可以明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者;而外部调用者也可以知道自己不可以碰哪里。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。
二,继承+多态:
继承和多态必须一起说。一旦割裂,就说明理解上已经误入歧途了。
先说继承:继承同时具有两种含义:其一是继承基类的方法,并做出自己的改变和/或扩展——号称解决了代码重用问题;其二是声明某个子类兼容于某基类(或者说,接口上完全兼容于基类),外部调用者可无需关注其差别(内部机制会自动把请求派发[dispatch]到合适的逻辑)。
再说多态:基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。
很显然,多态实际上是依附于继承的两种含义的:“改变”和“扩展”本身就意味着必须有机制去自动选用你改变/扩展过的版本,故无多态,则两种含义就不可能实现。
例:
农夫过河实验,可以很好的论证上面的说法:
由一开始的三个物种扩大到了五个物种,而且游戏的方法也由三带一增加到了五带二:这里使用继承和多态就会将题目变得尤为简便,物种的过河,生存状态以及名字等属性,吃东西的方法都是相同的,于是建立一个包括上述属性及方法的父类出来,再让子类继承,便会使整个编程过程简便许多;使每个物种继承父类的过河,存活状态等属性,再利用多态写一个吃东西的方法,将父类作为参数即可。以下为类的设计:
class Nature{ protected boolean isAlive = true; Scanner input = new Scanner(System.in); Nature(){ } public String name = new String(); public void setName(){ name = input.next(); } boolean crossRiver=false; public void setCrossRiver(boolean crossRiver) { this.crossRiver = crossRiver; } public boolean getCrossRive(){ return this.crossRiver; } public void eatSheep(Nature sheep, Nature farmer) { } public void eatCabbage(Nature cabbage, Nature farmer) { } public void showStatus() { } public void eatCarrot(Nature carrot, Nature farmer) { } public void eatRabbit(Nature rabbit, Nature farmer) { } } class Wolf extends Nature{ @Override public void setName() { System.out.println("Please set wolf's name"); super.setName(); System.out.println("啊呜~~~我"+name+"狼又回来了"); } //private boolean crossRiver=false; // public boolean hasCross=crossRiver; // public void setCrossRiver(boolean crossRiver) { // this.crossRiver = crossRiver; //} // public boolean getCrossRive(){ // return this.crossRiver; // } @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } @Override public void eatSheep(Nature sheep, Nature farmer) { if(sheep.getCrossRive()==crossRiver&& crossRiver != (farmer.getCrossRive())){ sheep.isAlive=false; } } public void eatRabbit(Nature rabbit,Nature farmer){ if(rabbit.getCrossRive()==crossRiver&& crossRiver != (farmer.getCrossRive())){ rabbit.isAlive=false; } } // public void eatSheep(Sheep sheep, Farmer farmer) { // if(sheep.getCrossRive()==crossRiver&& crossRiver != (farmer.getCrossRive())){ // sheep.isAlive=false; // } // } //public void showStatus() { // System.out.print("Wolf "+name+"狼is alive : true"); // System.out.print(" "); // if(crossRiver){ // System.out.println("Wolf "+name+"狼has Cross : ture"); // }else { // System.out.println("Wolf "+name+"狼has Cross : false"); // } // } @Override public void showStatus() { System.out.print("Wolf "+name+"狼is alive : true"); System.out.print(" "); if(crossRiver){ System.out.println("Wolf "+name+"狼has Cross : ture"); }else { System.out.println("Wolf "+name+"狼has Cross : false"); } } } class Sheep extends Nature{ Scanner input = new Scanner(System.in); //String name = new String(); @Override public void setName() { System.out.println("Please set sheep's name"); super.setName(); System.out.println("咩咩,我是可爱的小羊"+name); } // public void setName(){ // System.out.println("Please set sheep's name"); // name = input.next(); // System.out.println("咩咩,我是可爱的小羊"+name); //} //private boolean crossRiver=false; //public void setCrossRiver(boolean crossRiver) { // this.crossRiver = crossRiver; //} //public boolean getCrossRive(){ // return this.crossRiver; //} @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } // public boolean isAlive = true; // public boolean hasCross=crossRiver; //public void eatCabbage(Cabbage cabbage, Farmer farmer) { // if(cabbage.getCrossRive()==crossRiver&&crossRiver != farmer.getCrossRive()){ // cabbage.isAlive=false; // } // } @Override public void eatCabbage(Nature cabbage, Nature farmer) { if(cabbage.getCrossRive()==crossRiver&&crossRiver != farmer.getCrossRive()){ cabbage.isAlive=false; } } // public void showStatus() { // if(isAlive){ // System.out.print("Sheep "+name+"is alive : true"); // }else{ // System.out.print("Sheep "+name+"is alive : false"); // } // System.out.print(" "); // if(crossRiver){ // System.out.println("Sheep "+name+"has Cross : ture"); // }else { // System.out.println("Sheep "+name+"has Cross : false"); // } // // } @Override public void showStatus() { if(isAlive){ System.out.print("Sheep "+name+"is alive : true"); }else{ System.out.print("Sheep "+name+"is alive : false"); } System.out.print(" "); if(crossRiver){ System.out.println("Sheep "+name+"has Cross : ture"); }else { System.out.println("Sheep "+name+"has Cross : false"); } } } class Cabbage extends Nature{ //private boolean crossRiver=false; //public boolean isAlive = true; //public boolean hasCross=crossRiver; // public void setCrossRiver(boolean crossRiver) { // this.crossRiver = crossRiver; // } //public boolean getCrossRive(){ // return this.crossRiver; //} @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } // public void showStatus() { // if(isAlive){ // System.out.print("Cabbage is alive : true"); // }else{ // System.out.print("Cabbage is alive : false"); // } // System.out.print(" "); // if(crossRiver){ // System.out.print("Cabbage has Cross : ture"); // }else { // System.out.print("Cabbage has Cross : false"); // } // } @Override public void showStatus() { if(isAlive){ System.out.print("Cabbage is alive : true"); }else{ System.out.print("Cabbage is alive : false"); } System.out.print(" "); if(crossRiver){ System.out.print("Cabbage has Cross : ture"); }else { System.out.print("Cabbage has Cross : false\n"); } } } class Farmer extends Nature{ //private boolean crossRiver=false; //public void setCrossRiver(boolean crossRiver) { // this.crossRiver = crossRiver; //} //public boolean getCrossRive(){ // return this.crossRiver; //} @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } // public void showStatus() { // if(crossRiver){ // System.out.println("Farmer has Cross : ture"); // }else { // System.out.println("Farmer has Cross : false"); // } // } @Override public void showStatus() { if(crossRiver){ System.out.println("Farmer has Cross : ture"); }else { System.out.println("Farmer has Cross : false"); } } } class Rabbit extends Nature{ @Override public void setName() { System.out.println("Please set rabbit's name"); super.setName(); System.out.println("咕咕,我是迷人的小兔"+name); } @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } @Override public void showStatus() { if(isAlive){ System.out.print("Rabbit "+name+"is alive : true"); }else{ System.out.print("Rabbit "+name+"is alive : false"); } System.out.print(" "); if(crossRiver){ System.out.println("Rabbit "+name+"has Cross : ture"); }else { System.out.println("Rabbit "+name+"has Cross : false"); } } public void eatCarrot(Nature carrot,Nature farmer){ if(carrot.getCrossRive()==crossRiver&&crossRiver != farmer.getCrossRive()){ carrot.isAlive=false; } } @Override public void eatCabbage(Nature cabbage, Nature farmer) { if(cabbage.getCrossRive()==crossRiver&&crossRiver != farmer.getCrossRive()){ cabbage.isAlive=false; } } } class Carrot extends Nature{ @Override public void setCrossRiver(boolean crossRiver) { super.setCrossRiver(crossRiver); } @Override public boolean getCrossRive() { return super.getCrossRive(); } @Override public void showStatus() { if(isAlive){ System.out.print("Carrot is alive : true"); }else{ System.out.print("Carrot is alive : false"); } System.out.print(" "); if(crossRiver){ System.out.print("Carrot has Cross : ture"); }else { System.out.print("Carrot has Cross : false"); } } } class Boat{ boolean crossRive = false; public void setCrossRive(Farmer farmer) { crossRive = farmer.getCrossRive(); } }
其中若不使用继承,那么每个被注释掉的模块都要一个个被加上,可以看到基本都是些相同的属性,加上实属累赘。
接下来再复习一个重要的知识点———集合:
这里着重复习两个比较常用的:
1,ArrayList:
引用于:菜鸟教程
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.ArrayList; // 引入 ArrayList 类 ArrayList<E> objectName =new ArrayList<>(); // 初始化
常用方法: 1:添加元素 对象名.add()括号中为要的添加量; 2:访问元素 对象名.get()括号中为访问元素的序号; 3:修改元素 对象名.set(元素序号,要修改的值); 4:删除元素 对象名.remove()括号中为元素序号; 5:计算大小 对象名.size()无参;返回此动态数组的大小; 输出: 可以遍历循环输出,
for (String i : sites) { System.out.println(i); }
也可以直接println(对象名); 排序: Collections 类也是一个非常有用的类,位于 java.util 包中,提供的 sort() 方法可以对字符或数字列表进行排序。
Collections.sort(对象名); // 字母排序
2,HashMap: