一、封装
1.封装的概念
封装是把过程和数据包围起来,对数据的访问只能通过已经定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成完全自治、封装的对象,这些对象通过一个受保护的借口访问其他对象。封装是一个信息隐藏技术,在 java 中通过关键字 private ,protected 和 public 实现封装。封装把对象的所有组成部分融合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。适当的封装可以让程式码更容易理解和维护,也加强了程式码的安全性。
java 中对封装的理解:(将某些东西进行隐藏,然后提供相应的方式进行获取)
隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,就是把该隐藏的隐藏起来,该暴露的暴露出来,这就是封装性的设计思想。
2. 封装的好处:提高代码的安全性
3. 代码
package com.mxdx6;
/**
* @Auther:雨天_
* @Date: 2022/4/7 - 04 - 07 - 21:40
* @Descroption: com.mxdx6
* @version:1.0
*/
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
Girl g = new Girl();
/*g.age = 18;
System.out.println(g.age);
*/
//设置年龄
g.shezhiAge(18);
//读取年龄
System.out.println(g.duquAge());
}
}
package com.mxdx6;
/**
* @Auther:雨天_
* @Date: 2022/4/7 - 04 - 07 - 21:34
* @Descroption: com.mxdx6
* @version:1.0
*/
public class Girl {
//属性
private int age;
//读取年龄
public int duquAge(){
return age;
}
//设置年龄
public void shezhiAge(int age){
if(age >= 30){
this.age = 18;
}else{
this.age = age;
}
}
}
(代码)总结:对于属性 age ,加了修饰符 private ,外界对它的访问受到了限制。属性本身无法再加限制条件,只可通过定义方法加其他的限制条件。
4.以属性为案例进行封装:
(1)将属性私有化,被 private 修饰 -------->加入权限修饰符
一但加入权限修饰符,就不可随意被获取属性
(2)提供 public 修饰的方法可供访问/使用
(3)即使外界可通过方法来访问属性,但是也不可随意访问,因为在方法中也可加入限制条件
5.实际开发中,方法一般会写成getter setter 方法
IDEA的快捷键是: alt+insert ----->Getter and Setter
(1)
package com.mxdx6;
/**
* @Auther:雨天_
* @Date: 2022/4/7 - 04 - 07 - 21:34
* @Descroption: com.mxdx6
* @version:1.0
*/
public class Girl {
//属性
private int age;
private int sno;
private String name;
private double height;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//读取年龄
public int getAge(){
return age;
}
//设置年龄
public void setAge(int age){
if(age >= 30){
this.age = 18;
}else{
this.age = age;
}
}
}
(2)
package com.mxdx7;
/**
* @Auther:雨天_
* @Date: 2022/4/11 - 04 - 11 - 21:39
* @Descroption: com.mxdx7
* @version:1.0
*/
public class Student {
//属性
private int age;
private String name;
private String sex;
//加入对应的getter和setter方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
if ("男".equals(sex) || "女".equals(sex)){//sex判断男女
this.sex = sex;
}else{
this.sex = "男";
}
}
//加入构造器
public Student(){
}
public Student(int age,String name,String sex){
this.name = name;
//this.sex = sex;
this.setSex(sex);
this.age = age;
}
}
package com.mxdx7;
/**
* @Auther:雨天_
* @Date: 2022/4/11 - 04 - 11 - 21:39
* @Descroption: com.mxdx7
* @version:1.0
*/
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
//创建一个Student对象
Student s1 = new Student();
s1.setAge(19);
s1.setName("大聪明");
s1.setSex("女");
System.out.println(s1.getSex()+"-----"+s1.getName()+"-----"+s1.getAge());
Student s2 = new Student(18,"大微微","aadadaa");
System.out.println(s2.getSex()+"-----"+s2.getName()+"-----"+s2.getAge());
}
}
二、继承
【1】概念
1.类是对象的抽象,继承是对类的抽象。
由继承得到的类被称为子类(派生类),被继承的类成为父类(超类)。
2,概念:吸收现有的类的数据和行为,附属新功能,创建新类。
3.继承的好处:提高代码的复用性
4.代码演示:
先写父类,再写子类:
父类:Person
子类:Student
package com.mxdx8;
/**
* @Auther:雨天_
* @Date: 2022/4/13 - 04 - 13 - 13:24
* @Descroption: com.mxdx8
* @version:1.0
*/
public class Person {
//属性
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
//方法
public void eat(){
System.out.println("喜欢吃饭");
}
public void sleep(){
System.out.println("喜欢睡觉");
}
}
package com.mxdx8;
/**
* @Auther:雨天_
* @Date: 2022/4/13 - 04 - 13 - 13:24
* @Descroption: com.mxdx8
* @version:1.0
*/
public class Student extends Person {// java 中的继承是通过 extends 来实现的
//属性
private int sno;
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
//方法:
public void lie(){
System.out.println("被骗了十块钱");
}
}
package com.mxdx8;
/**
* @Auther:雨天_
* @Date: 2022/4/13 - 04 - 13 - 13:36
* @Descroption: com.mxdx8
* @version:1.0
*/
public class Test {
//这是一个main方法
public static void main(String[] args) {
//创建子类的 Student 的对象
Student s1 = new Student();
s1.setSno(0303);
s1.setAge(20);
s1.setHeight(175.2);
s1.setName("菲菲");
System.out.println("学生的名字为:"+s1.getName()+",学生的年纪为:"+s1.getAge()+",学生的身高为:"+s1.getHeight());
//访问方法
s1.lie();
s1.eat();
s1.sleep();
}
}
PS:父类 privite 修饰的内容,子类也继承。只是封装的特性阻碍了直接调用,但是也提供了间接调用的方式。
5.总结
(1)继承关系:子类继承父类是在一定关系范围内继承的
(2)继承的好处:
提高了代码的复用性(父类的内容,子类直接用);便于代码的扩展;是多态的前提
(3)一个父类可以有多个子类;一个子类只能有一个直接父类(可以间接的继承自其他类)。
(4)继承具有传递性:Object 是所有类的根基父类。所有累都直接或者间接的继承自 Object 。
【2】 权限修饰符
(1)privite:权限:在当前类中可以访问
package com.mxdx5;
public class Test01 {
private int age;//未添加Setter Getter 方法,不可以在不同类中访问
public void eat(){
System.out.println(age);
age = 10;
}
}
package com.mxdx5;
public class A {
//这是一个main方法
public static void main(String[] args) {
A a1 = new A();
a1.age(10);//不同类中不可以访问
}
}
(2)default(缺省修饰符):权限:同一个包下的其他类都可以访问
package com.mxdx5;
public class A {
int age;//default 一般不写,写了就出错
public void eat(){
System.out.println(age);
age = 10;
}
}
package com.mxdx5;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
A a1 = new A();
a1.age = 10;
}
}
(3)project:权限:最大到不同包下的子类
package com.mxdx5;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
A a1 = new A();
a1.age = 10;
}
}
package com.mxdx5;
public class A {
protected int age;
public void eat(){
System.out.println(age);
age = 10;
}
}
package com.mxdx6;
import com.mxdx5.A;
public class B extends A {//不同包下的子类依旧可以访问
public void a(){
System.out.println(age);
}
}
(4)public:权限:在整个项目中都可以访问
package com.mxdx5;
public class A {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println(age);
age = 10;
}
}
权限修饰符总结:
属性和方法:修饰符:privite default project public
类:修饰符:两种:default public
PS:
一般属性:用 privite 来修饰
方法:用 public 来修饰
【3】方法的重写
1.重写的发生:
发生在子类和父类中,子类对父类提供的方法不满意的时候,对父类方法进行重写。
2.重写的格式要求:
子类的方法名字和父类的必须一致,参数列表(个数,顺序,类型)也要和父类一致
3.代码:
package com.mxdx6;
public class Person {
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
package com.mxdx6;
public class Student extends Person{
public void study(){
System.out.println("学习");
}
public void sleep(){
System.out.println("不睡觉");
}
}
package com.mxdx6;
public class Test02 {
//这是一个main方法
public static void main(String[] args) {
Student s = new Student();
s.sleep();
}
}
4.内存:
5.重载和重写的区别:
重载:同一个类中,方法名相同,形参列表不同的时候,多个方法构成了重载
重写:在不同类中,子类对父类提供的方法不满意的时候,对父类的方法进行重写
【4】super
1.super . 指的是:父类的
2.super 可以修饰属性,也可以修饰方法:在子类的方法中,可以通过 super . 方法/属性显示来调用父类提供的方法/属性。(通常不写)
在特殊情况下:当子类和父类的方法/属性重名时,想使用父类的方法/属性时,必须加上super. ,只可通过super 方法/属性来调用
package com.mxdx2;
public class Person01 {
int age = 22;
public void eat(){
System.out.println("吃饭");
}
}
package com.mxdx2;
public class Student extends Person01{
double score;
int age = 11;
public void study(){
System.out.println("学习");
}
public void eat(){
System.out.println("吃米饭");
}
public void m(){
System.out.println(age);
System.out.println(this.age);
System.out.println(super.age);
eat();
this.eat();
super.eat();
}
}
package com.mxdx2;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
//创建一个Student的具体的对象
Student s1 = new Student();
s1.m();
}
}
3.super 修饰构造器
(1)(平时写空构造器第一行都有:super.----->作用:调用父类的空构造器,一般不写)
(2)如果构造器中显示已经调用super父类构造器,那么第一行就没有默认分配的super();了
(若构造器中显示的使用super();调用了父类构造器,那么super();就不会默认分配构造器了。)
(3)构造器中,super调用父类构造器和this调用子类构造器只能存在一个,两者不能共存。super构造器放在第一行,this构造器也放在第一行。
(4)在IDEA 中生成构造器的快捷键是:alt + insert----->constructer
附:继承条件下构造方法的执行过程:
(代码展示)
package com.mxdx4;
public class Person01 {
int age;
String name;
public Person01() {
}
public Person01(int age, String name) {
this.age = age;
this.name = name;
}
}
package com.mxdx4;
public class Student extends Person01{
double height;
public Student() {
}
public Student(double weight) {
this.height = height;
}
public Student(int age, String name, double height) {
super(age, name);
this.height = height;
}
}
package com.mxdx4;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
Student s = new Student(19,"feifei",160.8);
}
}
【5】object
1.概念
所有类都直接或者间接的继承自Object类,Object类是所有java 类的根基类;意味着所有 java 对象都拥有 Object 类的属性和方法。若在类的声明中未使用 extends 指明其父类,则默认继承Object类。
2.toString() 方法
(1)Object 类的toString() 方法的作用
(2)(方法的原理)
(3)使用 toString() 方法的时候,可读性不好。
例如:
package com.mxdx;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
//创建一个Person01类的具体的实例
Person01 p1 = new Person01(19,"dd",160.7);
System.out.println(p1);//com.mxdx.Person01@1b6d3586
System.out.println(p1.toString());//com.mxdx.Person01@1b6d3586
}
}
子类 Person01 对父类 Object 的 toString 方法不满意 ----> 对 toString 方法进行重写
package com.mxdx;
public class Person01 {
private int age;
private String name;
private double height;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public Person01() {
}
public Person01(int age, String name, double height) {
this.age = age;
this.name = name;
this.height = height;
}
public String toString(){
return "这是一个 Person01 对象,这个对象的名字是:"+name+",年龄是:"+age+",身高是:"+height;
}
}
package com.mxdx;
public class Test01 {
//这是一个main方法
public static void main(String[] args) {
//创建一个Person01类的具体的实例
Person01 p1 = new Person01(19,"dd",160.7);
System.out.println(p1);
System.out.println(p1.toString());
}
}
(4)总结:toString() 方法的作用就是对对象进行自我介绍,一般子类对父类提供的 toString() 方法都不满意,都得进行重写。
(5)IDEA 快捷键:alt + insert ------> toString()
3.equals
(1)作用:是对对象内容是否相等的比较方式,对象内容指的就是的属性
父类Object 提供的 equals 在比较地址,没有实际意义,一般不会使用父类提供的方法,而是在子类中对方法进行重写。
代码插入:
package com.mxdx;
/**
* @Auther:雨天_
* @Date: 2022/4/13 - 04 - 13 - 20:48
* @Descroption: com.mxdx
* @version:1.0
*/
public class Phone {
//属性
private String brand;
private double price;
private int year;
//方法
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
//构造器
public Phone() {
}
public Phone(String brand, double price, int year) {
this.brand = brand;
this.price = price;
this.year = year;
}
@Override
public String toString() {
return "Phone{" +
"brand='" + brand + '\'' +
", price=" + price +
", year=" + year +
'}';
}
//对equals方法进行重写
public boolean equals(Object obj){
//将 Obj 转为 Phone 类型:
Phone other = (Phone) obj;
if(this.getBrand()==other.getBrand()&&this.getPrice()==other.getPrice()&&this.getYear()==other.getYear()){
return true;
}
return false;
}
}
package com.mxdx;
/**
* @Auther:雨天_
* @Date: 2022/4/13 - 04 - 13 - 20:52
* @Descroption: com.mxdx
* @version:1.0
*/
public class Test02 {
//这是一个main方法
public static void main(String[] args) {
//创建一个 Phone 类的对象
Phone p = new Phone("huaweimate30",4099,2019);
Phone p1 = new Phone("huaweimate30",4099,2019);
//比较:
//==的作用:比较两边的值是否相等。相等返回true,不相等返回false
System.out.println(p==p1);//引用数据类型比较的是地址值,一定不相等,返回false
//Object中equals 方法:作用:比较对象具体内容是否相等
boolean flag = p.equals(p1);//点进源码,底层比较依旧是==,比较地址值
System.out.println(flag);
}
}
(2)instanceof(运算符)
(3)利用集成开发工具生成 equals 方法
eclipse:
IDEA:
// //对equals方法进行重写
// public boolean equals(Object obj){
// /*
// * a instanceof b
// * 判断 a 对象是否是 b 这个类的实例,是返回 true ,不是返回 false
// * */
// if(obj instanceof Phone){//属于 Phone 类的对象
// //将 Obj 转为 Phone 类型:
// Phone other = (Phone) obj;//原因:??
// if(this.getBrand()==other.getBrand()&&this.getPrice()==other.getPrice()&&this.getYear()==other.getYear()){
// return true;
// }
// }
// return false;
// }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Phone phone = (Phone) o;
return Double.compare(phone.price, price) == 0 && year == phone.year && Objects.equals(brand, phone.brand);
}
@Override
public int hashCode() {
return Objects.hash(brand, price, year);
}
【6】类和类之间的关系
1.代码展示:
package com.mxdx5;
public class Girl {
//属性
int age;
double weight;
String name;
//方法
public void watch(int d){//基本数据类型
System.out.println(d);
System.out.println(d + 100);
}
//谈恋爱的方法
public void love(Boy t){//引用数据类型
System.out.println("我男朋友的名字叫:"+t.name+"他的年龄是"+t.age);
t.good();
}
//构造器
public Girl(int age, double weight, String name) {
this.age = age;
this.weight = weight;
this.name = name;
}
}
package com.mxdx5;
public class Boy {
//属性
int age;
String name;
//方法
public void good(){
System.out.println("恋爱了我会一直对你好");
}
//构造器
public Boy(int age, String name) {
this.age = age;
this.name = name;
}
}
package com.mxdx5;
public class Test02 {
//这是一个main方法
public static void main(String[] args) {
//创建一个 Boy 类的具体的对象
Boy tqw = new Boy(19,"tqw");
//创建一个 Girl 类的具体的对象
Girl wyd = new Girl(19,120.4,"wyd");
//恋爱
wyd.love(tqw);
}
}
(1)面向对象的思维:找参与者。 ( 男孩和女孩类)
(2)方法的形参和方法的实参
(3)类和类可以产生关系
将一个类作为另一个类中方法的形参;将一个类作为另一个类的属性
package com.mxdx5;
public class Girl {
//属性
int age;
double weight;
String name;
Mom m /*= new Mom()*/;
//方法
public void watch(int d){//基本数据类型
System.out.println(d);
System.out.println(d + 100);
}
//谈恋爱的方法
public void love(Boy t){//引用数据类型
System.out.println("我男朋友的名字叫:"+t.name+"他的年龄是"+t.age);
t.good();
}
//女孩和妈妈聊天
public void wechat(){
m.talk();
}
//构造器
public Girl(int age, double weight, String name) {
this.age = age;
this.weight = weight;
this.name = name;
}
}
package com.mxdx5;
public class Boy {
//属性
int age;
String name;
//方法
public void good(){
System.out.println("我会一直对你好");
}
//构造器
public Boy(int age, String name) {
this.age = age;
this.name = name;
}
}
package com.mxdx5;
public class Mom {
public void talk(){
System.out.println("妈妈爱说好多事");
}
}
package com.mxdx5;
public class Test02 {
//这是一个main方法
public static void main(String[] args) {
//创建一个 Boy 类的具体的对象
Boy tqw = new Boy(19,"tqw");
//创建一个 Girl 类的具体的对象
Girl wyd = new Girl(19,120.4,"wyd");
//恋爱
wyd.love(tqw);
//女孩和妈妈微信聊天
wyd.m = new Mom();
wyd.wechat();
}
}
2.分类
(1)继承关系:继承指的是一个类(子类,子接口)继承另外的一个类(父类,父接口)的功能,并增加自己新功能的能力。在 java 中用 extends 明确标识,一般不具有争议性。
(2)实现关系:实现指的是一个 class 实现 interface 接口,实现是接口与类之间最常见的关系。在 java 中用 implements 明确标识。一般不具有争议性。
(3)依赖关系:依赖就是一个类 A 使用到了另一个类 B ,这种使用关系是偶然的、临时性的、非常弱的,但是类 B 的变化会影响到类 A 。表现在代码层面,让类 B 作为参数被类 A 在某个 method 方法中使用。
(4)关联关系:关联体现的是两个类之间语义级别的一种强依赖关系。不存在依赖关系的偶然性,关系也不是临时的,一般是长期性的,双方的关系一般是平等的,关联可以是单向、双向的。表现在代码层面,为被关联类 B 以类的属性形式出现在关联类 A 中,也可能是关联类 A 引用了一个被关联类 B 的全局变量。
(5)聚合关系:聚合是关联关系的一种特例,它体现的是整体与部分的关系,即 has-a 的关系。此时整体与部分是可分离的,它们可以具有各自的生命周期,部分可属于多个整体对象,也可为多个整体对象共享。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。
(6)组合关系:组合也是关联关系的一种特例,它体现的是一种 contains-a 的关系,这种关系比聚合更强,也称强聚合。它同样体现整体与部分的关系,但此时整体与部分是不可分的,整体的生命周期结束也意味着部分生命周期的结束。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。
-------------------------------------------------------------------------------------------------------------------------------
总结:继承和实现它们体现的是一种类和类、类和接口之间的纵向关系。其他四种关系体现的是一种类和类、或者类和接口之间的引用、横向关系,是比较难区分的。这四种关系都是语义级别的,所以从代码层面不能完全区分各种关系。
后四种关系表现的强弱程度依次是:组合>聚合>关联>依赖
三、多态
1.关系:多态与属性无关,多态指的是方法的多态,而不是属性的多态。
2.(代码分析)
package com.mxdx1;
public class Animal {
public void shout(){
System.out.println("我是小动物,我会叫");
}
}
package com.mxdx1;
public class Girl {
//女孩和猫玩
public void play(Cat cat){
cat.shout();
}
//女孩和狗玩
public void play(Dog dog){
dog.shout();
}
//女孩和小动物玩
public void play(Animal an){
an.shout();
}
}
package com.mxdx1;
public class Dog extends Animal{
public void shout(){
System.out.println("我是狗,我会汪汪");
}
public void guard(){
System.out.println("我会看好主人家的院子");
}
}
package com.mxdx1;
public class Tiger extends Animal{
public void eat(){
System.out.println("我是老虎,我吃肉");
}
public void shout(){
System.out.println("我是老虎,我吼叫");
}
}
package com.mxdx1;
public class Cat extends Animal{
public void shout(){
System.out.println("我会喵喵叫");
}
public void jump(){
System.out.println("我跳得高");
}
}
package com.mxdx1;
public class Test {
//这是一个main方法
public static void main(String[] args) {
//具体的猫
Cat c = new Cat();
//具体的小女孩
Girl g = new Girl();
//小女孩和猫玩
g.play(c);
//具体的狗
Dog d = new Dog();
//小女孩和狗玩
g.play(d);
//具体的小动物
Tiger ti = new Tiger();
Animal a =ti;
//小女孩和小动物玩
g.play(a);
}
}
(内存分析)
3.总结
(1)先有父类,再有子类 -------> 继承 先有子类,再有父类 -------->泛化
(2)什么是多态:多态指的是就是多种状态,同一个行为,不同的子类表现出来不同的状态。(同一个方法调用,对象不同产生不同的行为)
(3)多态的好处:为了提高代码的拓展性,符合面向对象的设计原则:开闭原则。
(开闭原则:指的是拓展是开放的,修改是关闭的。)
PS : 多太态可以提高拓展性,但是拓展性不是最好。(反射)
(4)多态的三个要素:继承、重写、父类引用指向子类对象
例:
//(父类引用指向子类对象)
Tiger ti = new Tiger();
Animal a = ti;
//合为一句
Animal a = new Tiger();
/*
=左侧 编译期类型
=右侧 运行期类型
*/
public void play(Animal an){//Animal an = an = new Tiger
an.shout();
}
/*
上面代码也是非常常见的应用场合:父类当方法的形参,传入的是具体的子类的对象,调用同一个方法,
根据传入的字类不同展现出来的效果也不同,构成了多态。
*/
4.向上转型和向下转型
public class Demo {
//这是一个main方法
public static void main(String[] args) {
Cat c = new Cat();
Animal a = c;
a.shout();
a.jump();//报错
}
}
将访问 weight 和 jump 属性:
public class Demo {
//这是一个main方法
public static void main(String[] args) {
Cat c = new Cat();
Animal a = c;//转型:向上转型
a.shout();
//加入转型的代码
//将Animal转为Cat类型
Cat cat = (Cat) a;//转型:向下转型
cat.jump();
cat.shout();
cat.weight = 90;
//a.weight = 90;
//a.jump();
}
}
Cat cat = (Cat) a;//对应内存分析
5.简单工厂模式
不仅可以使用父类做方法的形参,也可使用父类做方法的返回值类型,真是返回的对象可以是该类的任意一个子类对象。
简单工厂模式的实现,解决大量对象创建问题的一个解决方案,将创建和使用分开,工厂负责创建,使用直接调用即可。基本要求是:
(1)定义一个 static 方法,通过类名直接调用
(2)返回值类型是父类类型,返回的可以是任意其子类类型
(3)传入一个字符串类型的参数,工厂根据参数创建对应的子产品
代码示例:
package com.mxdx1;
public class Petstore {
public static Animal getAnimal(String name ){//多态的应用场合(二)
Animal a = null;
if("狗".equals(name)){//Name.equals("狗")--->这样写容易发生空指针异常
a = new Dog();
}
if("猫".equals(name)){
a = new Cat();
}
if("老虎".equals(name)){
a = new Tiger();
}
return a;
}
}
package com.mxdx1;
public class Test {
//这是一个main方法
public static void main(String[] args) {
//具体的小女孩
Girl g = new Girl();
//Tiger ti = new Tiger();
Animal a =Petstore.getAnimal("狗");
//小女孩和小动物玩
g.play(a);
}
}