三大特性
封装
生活案例:
ATM,电线
Java中封装的理解:
将某些东西进行隐藏,然后提供相应的方式进行获取。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a6lkrgif-1663170214750)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913210532575.png)]
我们程序设计追求“高内聚,低耦合”。
➢高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
➢低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,==把该隐藏的隐藏起来,该暴露的暴露出来。==这就是封装性的设计思想。
封装的好处:
提高代码的安全性
代码:
通过一个属性感受封装:
package com.yue.test01;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;}}
}
package com.yue.test01;public class Test {public static void main(String[] args) {//创建一个Girl类的对象:Girl g = new Girl();/*g.age = 36;System.out.println(g.age);*///设置年龄:g.shezhiAge(31);//读取年龄:System.out.println(g.duquAge());}
}
以上代码,对于属性age来说,我加了修饰符private,这样外界对它的访问就受到了限制,现在我还想加上其他的限制条件,但是在属性本身上没有办法再加了,所以我们通过定义方法来进行限制条件的添加。
以属性为案例:
进行封装:
(1)将属性私有化,被private修饰–》加入权限修饰符
一旦加入了权限修饰符,其他人不能随意获取这个属性
(2)提供public修饰的方法让别人访问/使用
(3)即使外界可通过方法来访问属性了,但是也不能随意访问,因为在方法中可以加入 限制条件。
读取设置方法命名
实际开发中,方法一般会写成 setter,getter方法:
可以用IDEA快捷键生成:alt+insert -->getter and setter:
public class Girl {//女孩//属性:private int age;//读取年龄:public int getAge(){return age;}//设置年龄:public void setAge(int age){if(age >= 30 ){this.age = 18;}else{this.age = age;}}
}
练习:
package com.yue.test2;public class Student {//属性:private int age;private String name;private String sex;//加入对应的setter和getter方法://IDEA快捷键生成:alt+insert -->getter and setterpublic 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.age = age;this.name = name;//this.sex = sex;this.setSex(sex);}
}
package com.yue.test2;public class Test {public static void main(String[] args) {//创建一个Student对象:Student s1 = new Student();s1.setName("aiyo");s1.setAge(19);s1.setSex("女");System.out.println(s1.getName()+"---"+s1.getAge()+"----"+s1.getSex());Student s2 = new Student(18,"菲菲","asdfasdfsadf");System.out.println(s2.getName()+"---"+s2.getAge()+"----"+s2.getSex());}
}
继承
类是对对象的抽象:
荣耀20 ,小米 红米3,华为 p40 pro —> 类:手机类
继承是对类的抽象:
学生类:Student:
属性:姓名,年龄,身高,编号
方法:吃饭,睡觉,喊叫,学习
教师类:Teacher:
属性:姓名,年龄,身高,编号
方法:吃饭,睡觉,喊叫,教学
共同的东西:
人类:
属性:姓名,年龄,身高
方法:吃饭,睡觉,喊叫
学生类/教师类/员工类 继承自 人类
定义代码:
先定义人类:
人类: —>父类,基类,超类
属性:姓名,年龄,身高
方法:吃饭,睡觉,喊叫
再定义 : —>子类,派生类
学生类:Student:
属性:学生编号
方法:学习
教师类:Teacher:
属性:教师编号
方法:教学
子类 继承自 父类
狗类:
属性:姓名,年龄,身高
方法:吃饭,睡觉,喊叫
我们的继承关系在合理的范围中进行的抽取 ,抽取出子类父类的关系:
出子类父类的关系:
学生类/教师类/员工类 继承 自 人类 —》合理
学生类/教师类/员工类 继承 自 狗类 —》不合理
总结:继承 就是 is - a 的关系
代码层面的解释:
先写父类,再写子类:
package com.yue.test03;public class Person {//属性:private int age;private String name;private double height;//提供setter getter方法: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.yue.test03;public class Student extends Person {//子类Student 继承(extends) 父类Person//属性:private int sno;//学号public int getSno() {return sno;}public void setSno(int sno) {this.sno = sno;}//方法:public void study(){System.out.println("学习");}
}
package com.yue.test03;public class Test {public static void main(String[] args) {//创建子类Student的对象Student s = new Student();s.setSno(101);s.setAge(15);s.setName("小猫");s.setHeight(180.4);System.out.println("名字为:"+s.getName()+",年纪:"+s.getAge());//访问方法:s.study();s.eat();s.sleep();}
}
继承的好处:
提高代码的复用性
父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了
总结:
(1)继承关系 :
父类/基类/超类
子类/派生类
子类继承父类一定在合理的范围进行继承的 子类 extends 父类
(2)继承的好处:
1.提高了代码的复用性,父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了
2.便于代码的扩展
3.为了以后多态的使用。是多态的前提。
(3)父类private修饰的内容,子类也继承过来了。(只是因为封装的特性阻碍了直接调用,但是提供了间接调用的方式,可以间接调用)
(4)一个父类可以有多个子类。
(5)一个子类只能有一个直接父类。
但是可以间接的继承自其它类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EWQsfqut-1663170214754)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913224815520.png)]
(6)继承具有传递性:
Student --》继承自 Person —》继承自Object
Object类是所有类的根基父类。
所有的类都直接或者间接的继承自Object。
内存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UtNhqolL-1663170214758)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225257827.png)]
权限修饰符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5XI1Ijgn-1663170214759)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225324068.png)]
private:
权限:在当前类中可以访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ArmPGOrG-1663170214760)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225619059.png)]
default:
缺省修饰符:权限:到同一个包下的其他类都可以访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hNwPF7a-1663170214761)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225627966.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HkDoVkUi-1663170214765)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225638010.png)]
protected:
权限:最大到不同包下的子类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVbQBBPk-1663170214766)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225709403.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ELUfZuhK-1663170214767)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913225720319.png)]
public:
在整个项目中都可以访问
总结:
属性,方法:修饰符:四种:private,缺省,protected,public
类:修饰符:两种:缺省,public
以后写代码
一般属性:用private修饰 ,方法:用public修饰
方法的重写
重写:
发生在子类和父类中,当子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
格式:
重写有严格的格式要求:
子类的方法名字和父类必须一致,参数列表(个数,类型,顺序)也要和父类一致。
代码:
public class Person {public void eat(){System.out.println("吃");}public void sleep(){System.out.println("睡");}
}
public class Student extends Person {public void study(){System.out.println("学习");}@overridepublic void eat(){System.out.println("我喜欢吃大盘鸡");}
}
运行结果:我喜欢吃大盘鸡
public class Test {public static void main(String[] args) {//创建一个Student类的对象:Student s = new Student();s.eat();}
}
内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cZWom40Q-1663170214769)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913230508368.png)]
重载和重写的区别:
重载:在同一个类中,方法名相同,形参列表不同时 ,多个方法构成了重载
重写:在不同的类中,子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L34NZLLy-1663170214771)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913230600990.png)]
super:
父类的
super可以修饰
可以修饰属性,可以修饰方法;
在子类的方法中,可以通过 super.属性 super.方法 的方式,显示的去调用父类提供的属性,方法。在通常情况下,super.可以省略不写:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-As157ac9-1663170214772)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913230856160.png)]
特殊情况下,当子类和父类的属性重名时,你要想使用父类的属性,必须加上修饰符super.,只能通过super.属性来调用
特殊情况下,当子类和父类的方法重名时,你要想使用父类的方法,必须加上修饰符super.,只能通过super.方法来调用
在这种情况下,super.就不可以省略不写。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wPNqedR3-1663170214774)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231023079.png)]
super修饰构造器:
其实我们平时写的构造器的第一行都有:super() -->作用:调用父类的空构造器,只是我们一般都省略不写
(所有构造器的第一行默认情况下都有super(),**但是**一旦你的构造器中显示的使用super调用了父类构造器,那么这个super()就不会给你默认分配了。如果构造器中没有显示的调用父类构造器的话,那么第一行都有super(),可以省略不写)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wumWQcfi-1663170214775)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231207475.png)]
如果构造器中已经显示的调用super父类构造器,那么它的第一行就没有默认分配的super();了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Q61pCPK-1663170214776)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231232120.png)]
在构造器中,super调用父类构造器和this调用子类构造器只能存在一个,两者不能共存:
因为super修饰构造器要放在第一行,this修饰构造器也要放在第一行:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPwX8vz4-1663170214778)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231340180.png)]
改正:二选一即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tXSEiw5n-1663170214781)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231404548.png)]
代码构造器快捷键:
以后写代码构造器的生成可以直接使用IDEA提供的快捷键:
alt+insert
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gXW5vH62-1663170214782)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231450187.png)]
继承条件下构造方法的执行过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yqYxNYks-1663170214784)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220913231633867.png)]
package com.yue.test10;public class Person {int age;String name;public Person(int age, String name) {super();this.age = age;this.name = name;}public Person() {}
}
public class Student extends Person {double height ;public Student() {}public Student(int age, String name, double height) {super(age, name);this.height = height;}
}
public class Test {public static void main(String[] args) {Student s = new Student(19,"star",160.8);}
}
Object类
所有类都直接或间接的继承自Object类,Object类是所有Java类的根基类。
意味着所有的Java对象都拥有Object类的属性和方法。
如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rHJgbPDR-1663170214786)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231025047.png)]
toString()方法
Object类的toString()的作用:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cYCsHGda-1663170214788)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231125066.png)]
原理:(知道原理也很重要,不是只要会敲代码)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lgr7ywvd-1663170214789)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231148616.png)]
现在使用toString方法的时候,打印出来的东西 “不好看”,对于其他人来说不友好,可读性不好
我们现在是想知道对象的信息,名字,年龄,身高。。。。。。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qXhB8mxK-1663170214789)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231228832.png)]
出现的问题:子类Student对父类Object提供的toString方法不满意,不满意---->对toString方法进行重写:
package com.msb.test01;
/*** @Auther: msb-zhaoss*/
public class Student /*extends Object*/{private String name;private int age;private double height;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}------------------------------------------------- public String toString() {return "这是一个Student对象,这个对象的名字:"+name+",年龄:"+age+",身高:"+height;}
}
测试类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVNDh3j5-1663170214790)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231446279.png)]
总结:toString的作用就是对对象进行“自我介绍”,一般子类对父类提供的toString都不满意,都进行重写。
IDEA提供了快捷键:
package com.msb.test01;
/*** @Auther: msb-zhaoss*/
public class Student /*extends Object*/{private String name;private int age;private double height;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public Student() {}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}/*public String toString() {return "这是一个Student对象,这个对象的名字:"+name+",年龄:"+age+",身高:"+height;}*/------------------------------------------------@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}
equals方法
instanceof
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcFpGLXJ-1663170214791)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231905176.png)]
利用集成开发工具生成equals方法
利用eclipse:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DkvUvsOJ-1663170214792)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231922460.png)]
利用idea:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PlRkkYRZ-1663170214793)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914231958123.png)]
类和类的关系
代码
总结:
【1】面向对象的思维:找参与者,找女孩类,找男孩类
【2】体会了什么叫方法的形参,什么叫方法的实参:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XbiChPie-1663170214793)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232134900.png)]
具体传入的内容 实参:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kCQmwtuY-1663170214794)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232154522.png)]
【3】类和类可以产生关系:
(1)将一个类作为另一个类中的方法的形参
(2)将一个类作为另一个类的属性
public class Girl {//属性:String name;double weight;Mom m /*= new Mom()*/;//方法:public void add(int a){//参数是基本数据类型System.out.println(a);System.out.println(a+100);}//谈恋爱的方法:public void love(Boy b){//参数是引用数据类型BoySystem.out.println("我男朋友的名字是:"+b.name+",我男朋友的年龄是:"+b.age);b.buy();}//女孩跟妈妈聊天:public void wechat(){m.say();}//构造器:public Girl(String name, double weight) {this.name = name;this.weight = weight;}
}
public class Boy {//属性:int age;String name;//方法:public void buy(){System.out.println("跟我谈恋爱,我给你买买买。。。");}//构造器:public Boy(int age, String name) {this.age = age;this.name = name;}
}
public class Mom {//方法:public void say(){System.out.println("妈妈唠唠叨叨 都是爱,听妈妈的话。。");}
}
public class Test {//这是一个main方法,是程序的入口:public static void main(String[] args) {//创建一个Boy类的具体的对象:Boy boy = new Boy(30,"鹿晗");//创建一个Girl类的具体的对象:Girl girl = new Girl("关晓彤",100);//谈恋爱://girl.love(boy);Boy boy2 = new Boy(35,"陈伟霆");girl.love(boy2);//还可以跟妈妈微信聊天:girl.m = new Mom();girl.wechat();}
}
总结(多看,达到理解)
一、继承关系
继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有争议性。在UML类图设计中,继承用一条带空心三角箭头的实线表示,从子类指向父类,或者子接口指向父接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7uxkzEC3-1663170214796)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232410763.png)]
二、实现关系
实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系。在Java中此类关系通过关键字implements明确标识,在设计时一般没有争议性。在UML类图设计中,实现用一条带空心三角箭头的虚线表示,从类指向实现的接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IyowoSwf-1663170214798)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232426187.png)]
三、依赖关系
简单的理解,依赖就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。表现在代码层面,==让类B作为参数被类A在某个method方法中使用。==在UML类图设计中,依赖关系用由类A指向类B的带箭头虚线表示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vcb3IONZ-1663170214799)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232444322.png)]
四、关联关系
关联体现的是两个类之间语义级别的一种强依赖关系,比如我和我的朋友,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。关联可以是单向、双向的。表现在代码层面,为被关联类B以类的属性形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。在UML类图设计中,关联关系用由关联类A指向被关联类B的带箭头实线表示,在关联的两端可以标注关联双方的角色和多重性标记。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZxZvzA7-1663170214800)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232523324.png)]
五、聚合关系
聚合是关联关系的一种特例,它体现的是整体与部分的关系,即has-a的关系。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。比如计算机与CPU、公司与员工的关系等,比如一个航母编队包括海空母舰、驱护舰艇、舰载飞机及核动力攻击潜艇等。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,聚合关系以空心菱形加实线箭头表示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XbrB9p8O-1663170214801)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232553944.png)]
六、组合关系
组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如人和人的大脑。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。在UML类图设计中,组合关系以实心菱形加实线箭头表示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EH3byOc-1663170214802)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232615565.png)]
七、总结
对于继承、实现这两种关系没多少疑问,它们体现的是一种类和类、或者类与接口间的纵向关系。其他的四种关系体现的是类和类、或者类与接口间的引用、横向关系,是比较难区分的,有很多事物间的关系要想准确定位是很难的。前面也提到,==这四种关系都是语义级别的,所以从代码层面并不能完全区分各种关系,==但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖。
多态(Polymorphism)
内存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DAh5ZVsR-1663170214803)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232746684.png)]
向下转型,向上转型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBWSYlkE-1663170214804)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232806626.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0rYpQyG-1663170214805)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232813468.png)]
如果现在我就想访问到eat()方法和weight属性:
public class Demo {//这是一个main方法,是程序的入口:public static void main(String[] args) {Pig p = new Pig();Animal an = p;//转型:向上转型an.shout();//加入转型的代码://将Animal转为Pig类型:Pig pig = (Pig)an ;//转型:向下转型pig.eat();pig.age = 10;pig.weight = 60.8;}
}
对应内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRpahi4J-1663170214806)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232856903.png)]
思考之前的equals方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hIhSssA6-1663170214807)(C:\Users\86178\AppData\Roaming\Typora\typora-user-images\image-20220914232916549.png)]
简单工厂设计模式
(这些案例多看看理解含义以及原理)
不仅可以使用父类做方法的形参,还可以使用父类做方法的返回值类型,真实返回的对象可以是该类的任意一个子类对象。
简单工厂模式的实现,它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。简单工厂模式的基本要求是
² 定义一个static方法,通过类名直接调用
² 返回值类型是父类类型,返回的可以是其任意子类类型
² 传入一个字符串类型的参数,工厂根据参数创建对应的子类产品
public class Test {public static void main(String[] args) {Girl g = new Girl();//Cat c = new Cat();//Dog d = new Dog();//Pig p = new Pig();Animal an = PetStore.getAnimal("狗");g.play(an);}
}
public class PetStore {//宠物店 ---》工厂类//方法:提供动物public static Animal getAnimal(String petName){//多态的应用场合(二)Animal an = null;if("猫".equals(petName)){//petName.equals("猫") --》这样写容易发生空指针异常an = new Cat();}if("狗".equals(petName)){an = new Dog();}if("猪".equals(petName)){an = new Pig();}return an;}
}
该类的任意一个子类对象。
简单工厂模式的实现,它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。简单工厂模式的基本要求是
² 定义一个static方法,通过类名直接调用
² 返回值类型是父类类型,返回的可以是其任意子类类型
² 传入一个字符串类型的参数,工厂根据参数创建对应的子类产品
public class Test {public static void main(String[] args) {Girl g = new Girl();//Cat c = new Cat();//Dog d = new Dog();//Pig p = new Pig();Animal an = PetStore.getAnimal("狗");g.play(an);}
}
public class PetStore {//宠物店 ---》工厂类//方法:提供动物public static Animal getAnimal(String petName){//多态的应用场合(二)Animal an = null;if("猫".equals(petName)){//petName.equals("猫") --》这样写容易发生空指针异常an = new Cat();}if("狗".equals(petName)){an = new Dog();}if("猪".equals(petName)){an = new Pig();}return an;}
}