* 生活中的多态:同一种物质,因环境不同而表现不同的形态。
* 程序中多态:同一个"接口",因不同的实现而执行不同的操作。
* 多态和方法的重写经常结合使用,子类重写父类的方法,将父类作为参数类型进行传入,执行时传入子类的实例,最终执行是子类重写后的方法。
* 多态优点: 提高了代码的扩展性和可维护性。
* 多态在java中实现的前提:
1.继承 2.方法的重写 3.父类引用指向子类
* 多态在java中实现的步骤。
* 1.建立继承关系
* 2.在编译时将父类作为形参(范围大一点,模糊一点)
* 3.在运行时将子类对象作为实参,执行的子类重写后的方法。
public class Dog extends Animal { @Override public void shout() { System.out.println("汪汪汪~~~~~~~~~~~"); } }
public class Cat extends Animal { @Override public void shout() { System.out.println("喵喵喵~~~~~~~~~~~"); } }
public class Animal { String name; int age; public Animal(){ } public Animal(String name,int age){ this.name=name; this.age=age; } public void shout(){ System.out.println("动物在叫....."); } }
public class TestAnimal { public static void testShout(Animal a) { System.out.println("比赛开始...."); a.shout(); } public static void main(String[] args) { Dog dog = new Dog(); testShout(dog); Cat cat = new Cat(); testShout(cat); testShout(new Duck()); } }
* 类型转换
* 1.子类转换为父类--->自动转化 (向上转型),访问的是父类的属性,调用的是子类重写父类后的方法。
* a.子类向上转型成父类,上转型对象不能操作子类新增的成员变量和方法。
* b.上转型对象可以操作子类继承或重写的成员变量和方法
* c.如果子类重写了父类的某个方法,上转型对象调用该方法时,是调用的重写方法。
* 2.父类转换为子类:强制转换(向下转型)
public class TestAnimal { public static void testShout(Animal a) { System.out.println("比赛开始...."); a.shout(); } public static void main(String[] args) { // 子类自身new自身,可以调用父类中继承的方法,属性和子类特有的方法,属性 // Dog dog =new Dog(); // dog.color="黄色"; // dog.watchDoor(); // Animal animal = new Dog();//向上转型 // animal.color //无法访问子类特有属性 // animal.watchDoor()//无法访问子类特有的方法。 // 上转型对象可以操作子类继承或重写的成员变量和方法 // animal.name="大黄"; // animal.shout();//执行子类重写后的方法。 Animal a = new Dog();//向上转型 Dog d = (Dog)a;//向下转型 d.shout(); } }
---------------------------------------------------------------分割线------------------------------------------------------------------------
public class Driver { public void drive(Car c){ System.out.println("我是A照驾驶员,我要开车.."); c.run(); } public static void main(String[] args) { Driver driver = new Driver(); driver.drive(new Benz()); driver.drive(new Bmw()); System.out.println("*********************"); //向上转型: Car c = new Benz(); System.out.println(c.name);//访问是父类的属性 c.run();//调用子类重写后的方法 } }
* final关键字
* 1.使用final修饰变量,该变量就变成常量,在运行的过程中无法重新赋值。
* 2.使用final修饰方法,该方法无法在子类中重写
* 3.使用final修饰的类,不能被继承(派生其他子类)
* JDK中常见的final修饰的类
* java.lang.Math
* java.lang.String
//public final class TestFinal { public class TestFinal { public void test(){ final int i=10; // i=20; //常量在运行的过程中无法重新赋值 } public final void test2(){ } } public class TestFinalSub extends TestFinal { //使用final修饰的方法无法被子类重写 // public void test2(){ // // } }
*抽象方法: 使用abstract修饰的方法,抽象方法没有方法体.
*抽象类: 使用abstract修饰的类,抽象类中可以包含抽象方法。非抽象类不能包含抽象方法。
*包含抽象方法的类一定是抽象类, 抽象类中可以没有抽象方法。
*抽象类中可以包含构造方法,但是不能使用new关键字创建抽象类的对象.(抽象类不能new)
*Person p = new Person();//错误
public abstract class Person { String name; int age; public Person(){ } public void intro(){ System.out.println("姓名:"+name); System.out.println("年龄:"+age); } //吃的方法 public abstract void eating(); }
/** * 子类继承了抽象类,就必须重写(实现)父类中抽象方法。 * */ public class Chinese extends Person { public Chinese() { } public Chinese(String name,int age){ this.name=name; this.age=age; } // 重写父类中抽象方法 @Override public void eating() { System.out.println("我是中国人,我喜欢吃饺子!"); } }
public class American extends Person { public American() { } public American(String name,int age){ this.name=name; this.age=age; } @Override public void eating() { System.out.println("我是美国佬,我喜欢吃牛排!"); } public static void main(String[] args) { Person p = new Chinese("小三",18); p.intro(); p.eating(); Person p2 = new American("rose",20); p2.intro(); p2.eating(); } }
23种java设计模式之一工厂模式(GOF):(简单工厂模式)
简单工厂模式又叫静态工厂方法,可以通过其生成产品,可以降低因生成生成产品而导致的耦合性过强。(解耦合)
简单工厂模式(静态工厂方法):属于创建型模式,主要用生成"产品"。
* 工厂模式的命名:xxxFactory--->生成xxx
*需求:创建一个生成斧头的工厂,根据用户传入的参数生产相应斧头并返回
* 如果参数为steel--->生成SteelAxe的一个对象
* 如果参数为stone--->生成StoneAxe的一个对象
*如何实现工厂模式?
* 1.编写父类和子类或接口和实现类
* 2.编写静态的工厂方法,返回值类型为父类或接口。--->多态
* 3.根据用户的需求动态创建子类的实例,并返回。
public abstract class Axe { public abstract void chop(); }
public class StoneAxe extends Axe { @Override public void chop() { System.out.println("我是石斧,砍日本人很钝!"); } }
public class SteelAxe extends Axe { @Override public void chop() { System.out.println("我是铁斧,砍日本人锋利!"); } }
public class AxeFactory { /** * 负责创建产品(斧头) * @param ch * @return */ public static Axe getInstance(String ch){ Axe axe=null; if(ch.equals("steel")){ axe = new SteelAxe(); }else if(ch.equals("stone")){ axe = new StoneAxe(); } return axe; } public static void main(String[] args) { Axe axe = AxeFactory.getInstance("steel"); axe.chop(); System.out.println("*********************"); Axe axe2 = AxeFactory.getInstance("stone"); axe2.chop(); } }
接口:
*java中定义接口使用的interface关键字
*java中的接口看作一种规范,接口中所有的方法都是抽象方法,接口中所有的变量都是常量
*接口中的方法默认的修饰符为 public abstract
* void fly()<===>public abstract void fly();
*接口中的成员变量默认修饰符为:public static final
* double PI=3.14;<====>public static final double PI=3.14;
public interface IFly { //public static final double PI=3.14; double PI=3.14; //public abstract void fly(); void fly(); }
/** * 一个类实现接口利用implements关键字,一旦实现了接口就必须重写接口中抽象方法。 * 修饰符 class 类名 implements 接口{ * * } * */ public class Superman implements IFly{ /** * 重写(实现)了接口中抽象方法 */ @Override public void fly() { System.out.println("我是超人,内裤外穿,举手就能飞......"); } }
public class Plane implements IFly{ @Override public void fly() { System.out.println("我是飞机,我加油就能飞....."); } }
public class Bird implements IFly { @Override public void fly() { System.out.println("我是一只小小鸟,我要展翅高翔....."); } }
/** * 利用接口,实现类,方法的重写完成多态 */ public class Test { public void testFly(IFly ifly){ ifly.fly(); } public static void main(String[] args) { Test test = new Test(); test.testFly(new Plane()); test.testFly(new Superman()); test.testFly(new Bird()); } }