多态的特点:
必须发生父子关系
重写方法
父类的变量指向子类的对象
抽象一定多态
目录
🍜多态案例一、面馆
Test类、People类、Cn 类、En类
Cn类和En类分别继承People类
Test类中含一个eatPlace()方法
主要通过父类变量指向子类的对象,传入父类变量,获取不同Cn、En两个子类的eat()方法,多态对eat()方法的重写,并通过父类的指引指向两个子类的eat()方法
public class Test {
public static void main(String[] args) {
Pe c=new Cn();
eatPlace(c);
Pe e=new En();
eatPlace(e);
}
//此处只用写一个eatPlace
public static void eatPlace(Pe p){
p.eat();
}
}
class People{
public void eat(){
}
}
class Cn extends People{
@Override
public void eat(){
System.out.println("中国人吃饭");
}
}
class En extends People{
public void eat(){
System.out.println("外国人吃饭");
}
}
Pe e=new En();
eatPlace(e);//此处调用eatPlace(父类变量)但结果却是En子类的eat()方法
Pe c=new Cn();
eatPlace(c);
🍜多态案例二、汽车工厂(简单的工厂模式)
Car类(父类)Adi类(子类)Bchi(子类)Test(测试类)Factory(工厂类)
通过工厂类的makeCar(参数),根据放入的零件造不同的车
弊端:每当工厂想造别的车辆时,就需要修改源代码,不易维护
public class Test {
public static void main(String[] args) {
Car c=Factory.makeCar("Adi");
c.run();
}
}
class Factory{
//工厂理论上不能属于对象,应该只有一个工厂隶属于类,
//这种写反导致,工厂一旦增加新的车辆,就需要改源代码
public static Car makeCar(String c){
if("Adi".equals(c)){
return new Adi();
}else if("Bchi".equals(c)){
return new Bchi();
}else{
System.out.println("只能制造Adi和Bchi");
return null;
}
}
}
class Car{
public void run(){
}
}
class Adi extends Car{
public Adi(){
System.out.println("Adi~~~~~");
}
public void run(){
System.out.println("runAdi~~~~");
}
}
class Bchi extends Car{
public Bchi(){
System.out.println("Bchi~~~~~");
}
public void run(){
System.out.println("runBchi~~~~");
}
}
优化方法:将工厂分化,为每一个车建一个类专属的工厂类,往后一旦需要增加其他汽车的制造,直接添加代码即可,不用修改之前的代码(当然这也有弊端)
🍜多态案例三、泡茶流程(简单的模板模式)
Tea类(父类),ChaTea类(子类),Coffee类(子类),Drink类(测试类)
两个子类的流程方法因为大部分一样,所以写入父类进行继承,但有一个wawa()等待的方法不一样,所以将其变成抽象方法,让子类重写
为了不让外界修改正确的泡茶流程,因此将整个流程方法进行封装在一个方法里LiuCheng(),并不能为子类继承,final修饰此方法
public class Drink {
public static void main(String[] args) {
//这里过于繁琐
// t.guLuGuLu();
// t.wuwuwu();
// t.wawa();
// t.drink();
Tea.LiuCheng(new ChaTea());//即便如此流程顺序也会被他人修改
//使用final修饰方法,便不能被子类继承
}
}
abstract class Tea{
public void guLuGuLu(){
System.out.println("烧水~~~~~");
}
public void wuwuwu(){
System.out.println("水烧开了~~~~~");
}
//抽象方法无方法体,此处的放入方法两则不一样所以必须重写abstract
public abstract void wawa();
public void drink(){
System.out.println("饮用~~~~~~~");
}
//此处直接一个方法调用全部流程
public final static void LiuCheng(Tea t){
t.guLuGuLu();
t.wuwuwu();
t.wawa();
t.drink();
}
}
//茶叶类
class ChaTea extends Tea{
public void wawa(){
System.out.println("放入茶叶等待~~~~~");
}
}
//咖啡类
class Coffee extends Tea{
public void wawa(){
System.out.println("放入咖啡等待~~~~~");
}
}
二分查找
释:
···即有三个指向,min
,mid
,max
,如图位置,mid=mid+(max-min)/2
,每次取中间=mid,判断查询的数是否大于mid
,大于则在mid
右边,将min
移动到mid+1
的索引位置,反之则在mid
左边,将max
移动到mid-1
的位置,直到Su[mid]\==Su[index]
或者min>=max
时结束
代码:
public class Test {
//分支查询
public static void main(String[] args) {
ArrayList01 a=new ArrayList01();
int[] gg=new int[]{1,2,3,4,5};
int len=gg.length;
System.out.println(len);
//System.out.println(gg[gg.length]);
int num=3;
int min=0;
int max=gg.length;
int mid;
while(min<=max){
mid=min+(max-min)/2;
if(gg[mid]==num){
System.out.println(mid);
return;
}else if(gg[mid]<num){
min=mid+1;
}else{
}
}
}
}