目录
13 多态(语法)
多态就是一个面向对象语言中的使用方法。
13.1 多态最基础的使用方式
多态使用最基础的结构:父类引用指向子类实例。
父类 引用 = new 子类();
public class A {
}public class B extends A{
}public static void main(String[] args) {
A a = new B();
}
13.2 多态在哪里?
多态最表面的理解 ,就是多种形态。
因为父类引用与子类实例 之间 是一对多的关系。
所以同一个父类引用,可以指向多个不同的子类实例。
A a ;//这个a的引用,可以指向三种不同的实例。
a = new C();
a = new B();
a = new A();
13.3 可以调用哪些方法
当父类引用指向子类实例时,父类引用可以打点调用哪些方法?
① 只能调用在父类中声明过的方法。 因为引用是一个父类的类型。
② 可以调用父类中的方法。
③ 子类重写的方法。
14 多态的一般使用格式
使用父类引用做为方法的形参。
使用不同子类实例做为方法的实参。
public class A { |
public class B extends A{ |
public class C extends A{ |
public class Test { |
16 练习:学校打印老师信息
学校老师(Teacher):每位老师都有打印信息的方式。
老师有姓名(name)、年龄(age)、工资(salary)老师还有外语老师、计算机老师、注册会计老师
外语老师(LanaguageTeacher)有外语语种(languages),外语等级(grade)
计算机老师(ComputerTeacher)有计算机语种(languages),项目职务(post)
注册会计老师(AccountantTeacher)有注册会计师证(id,保存证件编号就可以),注册会计师时间(date)
写一个学校类(School)。学校类负责打印每位教员的信息。
public class Teacher {
private String name;
private int age;
private double salary;
public Teacher() {
}
public Teacher(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
}
public class LanaguageTeacher extends Teacher{
private String languages;
private int grade;
public LanaguageTeacher() {
}
public LanaguageTeacher(String name, int age, double salary, String languages, int grade) {
super(name, age, salary);
this.languages = languages;
this.grade = grade;
}
@Override
public String toString() {
return "LanaguageTeacher{" +
"languages='" + languages + '\'' +
", grade=" + grade +
"} " + super.toString();
}
}
public class ComputerTeacher extends Teacher{
private String lanaguages;
private String post;
public ComputerTeacher() {
}
public ComputerTeacher(String name, int age, double salary, String lanaguages, String post) {
super(name, age, salary);
this.lanaguages = lanaguages;
this.post = post;
}
@Override
public String toString() {
return "ComputerTeacher{" +
"lanaguages='" + lanaguages + '\'' +
", post='" + post + '\'' +
"} " + super.toString();
}
}
public static void main(String[] args) {
LanaguageTeacher teacher1 = new LanaguageTeacher();
teacher1.setGrade(8);
teacher1.setLanguages("英语");
teacher1.setAge(25);
teacher1.setSalary(888888);
teacher1.setName("张老师");
ComputerTeacher teacher2 = new ComputerTeacher();
teacher2.setAge(25);
teacher2.setSalary(9999999);
teacher2.setName("孙老师");
teacher2.setLanaguages("Java");
teacher2.setPost("项目经理");
School school = new School();
school.print(teacher1);
school.print(teacher2);
}
17 练习:写一个“愤怒的小鸟”
我们有很多种小鸟(Bird),每种小鸟都有飞(fly)的行为。
还有一个弹弓(Slingshot),弹弓有一个弹射的方法,弹射的方法将把小鸟弹出去。
之后小鸟使用自己飞行的方法飞向小猪。(这是我们不讨论猪(不是鄙视它),只讨论小鸟)
各种小鸟不同飞的方式:
红火:红色小鸟,飞行方式:正常。
蓝冰:蓝色小鸟,飞行方式:分成3个。
黄风:黄色小鸟,飞行方式:加速。
public class Bird {
private String name;
private String color;
public Bird() {
}
public Bird(String name, String color) {
this.name = name;
this.color = color;
}
/**
* 鸟类的飞行方法。但是不知道鸟怎么飞?
*/
public void fly(){
}
}
public class RedBird extends Bird{
public RedBird() {
this.setName("红火");
this.setColor("红色");
}
@Override
public void fly() {
System.out.println(this.getColor()+"颜色的"+this.getName()+",正常飞");
}
}
public class Slingshot {
public void shot(Bird bird){
bird.fly();
}
}
编写测试类:
public class Test {
public static void main(String[] args) {
RedBird redBird1 = new RedBird();
Slingshot slingshot = new Slingshot();
slingshot.shot(redBird1);
}
}
18 修饰符final关键字
final修饰符只能修饰到如下几个地方:
① final 变量 =》表示这是一个常量值。不可以被修改
② final 方法 =》表示这个方法不可以被重写。不可以被修改。
③ final 类 =》表示这个类不可以被继承。不可以被修改。
常量命名的规范:全大写;每个单词之间用_分隔
例如:final int DAY_OF_YEAR = 365;
19 修饰符static关键字
static 中文名 静态
19.1 static可以修饰3个地方
① 代码块 静态代码块
② 属性 静态属性
③ 方法 静态方法
19.2 静态代码块
静态代码块一定是写在类中的。
静态代码块是在类加载时被执行的。而且只会执行一次。
静态代码块的作用是为了给静态属性进行初始化操作。
public class A {
static {
System.out.println("静态代码块!");
}
public A() {
System.out.println("A类的构造方法!");
}
public static void main(String[] args) {
new A();
new A();
}
}
19.3 静态属性
为实例属性增加static修饰符之后。属性就变成了静态属性。
public class A {
private static int i ;//静态属性
private int j ;//实例属性}
实例属性是属于每一个实例的。第一个实例都有自己的实例属性。实例属性是使用构造方法进行初始化。
静态属性是属于当前整个类的。这个类的每一个实例都共用同一个静态属性。
静态属性是在类加载时就创建了。使用静态代码码进行初始化操作。
静态属性的使用方法有二种:
① 对象名.静态属性
② 类名.静态属性
19.4 静态方法
静态方法属于当前整个类的。使用 类名.静态方法() 调用。
使用静态方法来操作静态属性。
一般算法类的公式,都会写成静态方法。
Arrays.sort();给数组进行升序排序。
20 单例模式
20.1 什么是单例模式
单例模式:表示一个类只能去创建一个实例。
20.2 单例模式的第一步:私有化构造方法
第一步:私有构造方法。构造方法就只能在类内调用。
所以:实例只能在类内创建。
第二步:在类内创建实例。
第三步:让外部通过本类的静态方法来获取实例。
20.3 饿汉模式
public class SingletonA {
//第二步:本类中创建自己的静态实例。
private static SingletonA singletonA = new SingletonA();
//第一步:私有构造方法
private SingletonA() {
}
//第三步:静态方法,通过 类名.getSingletonA();
public static SingletonA getSingletonA() {
return singletonA;
}
}
20.4 懒汉模式
public class SingletonB {
private static SingletonB singletonB;
private SingletonB() {
}
public static SingletonB getSingletonB() {
if(singletonB == null) {
singletonB = new SingletonB();
}
return singletonB;
}
}
21 披萨工厂
21.1编写一系列披萨类
public class SeafoodSupremePizza {
public void prepare(){
System.out.println("备料:大虾、蟹柳等丰富海鲜美味荟萃,配上酸甜菠萝、青椒,海鲜美味扑面而来!");
}
public void make(){
System.out.println("制作海鲜至尊!");
}
public void bake(){
System.out.println("烘焙");
}
public void cut(){
System.out.println("刀切");
}
public void box(){
System.out.println("装盒");
}
}
public class SuperSupremePizza {
public void prepare(){
System.out.println("备料:腊肉肠、意式香肠、火腿、五香牛肉、五香猪肉,搭配菠萝、蘑菇、洋葱、青椒等,如此丰盛馅料,口口都是令人满足的好滋味!");
}
public void make(){
System.out.println("制作超级至尊!");
}
public void bake(){
System.out.println("烘焙");
}
public void cut(){
System.out.println("刀切");
}
public void box(){
System.out.println("装盒");
}
}
编写创建披萨的工厂类:
public class PizzaFactory {
public static SeafoodSupremePizza createSeafoodSupremePizza(){
SeafoodSupremePizza seafoodSupremePizza = new SeafoodSupremePizza();
seafoodSupremePizza.prepare();
seafoodSupremePizza.make();
seafoodSupremePizza.bake();
seafoodSupremePizza.cut();
seafoodSupremePizza.box();
return seafoodSupremePizza;
}
public static SuperSupremePizza createSuperSupremePizza(){
SuperSupremePizza superSupremePizza = new SuperSupremePizza();
superSupremePizza.prepare();
superSupremePizza.make();
superSupremePizza.bake();
superSupremePizza.cut();
superSupremePizza.box();
return superSupremePizza;
}
}
编写测试类:
public class Test {
public static void main(String[] args) {
SeafoodSupremePizza seafoodSupremePizza = PizzaFactory.createSeafoodSupremePizza();
SuperSupremePizza superSupremePizza = PizzaFactory.createSuperSupremePizza();
}
}
21.2 优化:使用封装
设计模式原则:
①(分开封装)找出应用中可能需求变化的代码,把它们独立出来,不要和那些不需要变化的的代码混在一起。
变化部分:备料,制作
不变化部分:烘焙,用刀切,装盒
需要将 变化 和 不变化 的分开封装。
变化:封装到每一个不同的披萨类中。因为第一个不同的披萨类都不一样。
不变化 : 可以封装到披萨父类中。因为每一个披萨都一样。
public class Pizza {
public void prepare(){
}
public void make(){
}
public void bake(){
System.out.println("烘焙");
}
public void cut(){
System.out.println("刀切");
}
public void box(){
System.out.println("装盒");
}
}
public class SeafoodSupremePizza extends Pizza{
public void prepare(){
System.out.println("备料:大虾、蟹柳等丰富海鲜美味荟萃,配上酸甜菠萝、青椒,海鲜美味扑面而来!");
}
public void make(){
System.out.println("制作海鲜至尊!");
}
}
public class SuperSupremePizza extends Pizza {
public void prepare(){
System.out.println("备料:腊肉肠、意式香肠、火腿、五香牛肉、五香猪肉,搭配菠萝、蘑菇、洋葱、青椒等,如此丰盛馅料,口口都是令人满足的好滋味!");
}
public void make(){
System.out.println("制作超级至尊!");
}
}
针对创建披萨的工厂进行封装。(两种方式)
变化 :披萨对象的实例化。 如何发现变化的内容是对象的创建。就要使用工厂将创建的部分进行单独的封装。
不变化 :披萨的制作过程。就这5步。
public class PizzaFactory {
// public static Pizza create(int i){
// switch (i){
// case 1:return new SeafoodSupremePizza();
// case 2:return new SuperSupremePizza();
// case 3:return new SausageBitePizza();
// case 4:return new DeliciousBacon();
// }
// return null;
// }
// public static Pizza getPizza(int i){
// Pizza pizza=create(i);
// pizza.make();
// pizza.prepare();
// pizza.bake();
// pizza.cut();
// pizza.box();
// return pizza;
// }
public static Pizza getPizza(int i){
Pizza pizza=null;
switch (i) {
case 1: pizza= new SeafoodSupremePizza();
case 2: pizza= new SuperSupremePizza();
case 3: pizza= new SausageBitePizza();
case 4: pizza= new DeliciousBacon();
}
pizza.make();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}