java小白训练营day06-OOP:面向对象+封装+继承+多态
Posted 长安紫薯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java小白训练营day06-OOP:面向对象+封装+继承+多态相关的知识,希望对你有一定的参考价值。
文章目录
面向对象
是一种编程思想,编写程序时如何下手,怎么去解决实际问题。
面向过程和面向对象的区别?
OPP Procedure Oriented Programming 早期编程是思想推崇面向过程的思考(c语言、pascal语言)
OOP Object Oriented Programming 现今主流的编程思想推崇面向对象的思考(c++、java、python、c#)
案例:把大象装入冰箱
面向过程的思考方式:
把一个大的问题拆分成多个小问题,按步骤完成。
步骤:
1)把冰箱门打开
2)把大象放入
3)把冰箱门关上
面向过程的思考,关注处理问题的过程。
面向对象的思考方式:
1)找对象(实体、名词)大象和冰箱
2)分析大象的特质(大耳朵,小尾巴,粗腿)和行为(走,扇耳朵),分析冰箱的特质(容量、温度)和行为(开门、关门)
3)把冰箱门打开,把大象放入,把冰箱门关上
面向过程和面向对象的思考问题方式不同,面向过程关注过程,步骤;面向对象关注实体(对象)对象行为
案例:我周日去超市买葡萄、水饺
面向对象方式思考:
1)找实体(名称)
创建所有的商品的实例-建模(建立模型)(葡萄、水饺、面包、小青菜、菠菜、豆腐。。。。500种)
2)具体买葡萄、水饺
面向对象非常麻烦,它要花大量时间去构建目前来说无用的实体
这样做有什么意义呢?
需求变了,老婆说了,她想吃椰蓉面包
此时面向过程是无法适应的,它之前只关心之前的需要中的内容,只有葡萄、水饺,没有面包。怎么解决?重新设计。
面向对象,之前已经对“面包”进行了建模。这时面向对象的优点就体现了,需要变化了。但是我们只需少量改动即可使用。
面向过程的思考,速度快,更加贴近实际开发。(按需而动)
面向对象的思考,速度慢,构建对象是(实体)想的多想的全,当需求发生变化(需求变更),面向过程就需要改大量的代码,甚至推到重来。工作量巨大,时间没了。面向对象需求变更就小(设计者能力)(按事务发展经验之谈)
实际中开设按面向对象设计,然后按面向过程的设计。这样不是设计过度。两种设计思想相结合。
面向对象的三大特征
封装、继承、多态
封装 encapsulation
隐藏对象的细节
案例:手机
我们不知道手机是如何工作的,它如何去拨打电话就能和别人连线,如果把点信号转换成声音呢?。。。这些细节我们都不知道,但我们照样可以使用手机。
怎么拨号,怎么上网wifi
这些细节都被包装起来,而这些包装的内容对于使用者不用知道。它关心怎么拨号,怎么上wifi,聊微信,聊QQ
封装就是把用户不需要关心的内容进行隐藏,这有什么好处呢?用户关心的内容越少越好,使用起来就越方便。
案例:开车
你懂发动机吗?你懂轮胎型号吗?你懂加油有什么要注意的吗?
都不懂,只懂开车,方向盘,油门,刹车。
java语言中如何体现封装
1)把类的属性(特质、特征)变成私有,不允许直接访问 private 私有
Phone phone = new Phone();
phone.key 按钮,
phone.call() 拨打电话
2)设置get 获取和set方法 设置
不标准的写法
package cn.tedu.entity;
//entiy 就叫实体
/*
* 创建一个类Phone,体现封装
* 1)私有属性
* 2)对应get和set放
* 私有属性不允许外界直接访问,只能通过对应get和set方法访问
*/
public class Phone {
public String key; //按键
//在类中利用main方法进行测试
public static void main(String[] args) {
//创建对象实例,才可以调用它的属性
Phone phone = new Phone(); //创建对象
phone.key = "136";
System.out.println(phone.key);
}
}
package cn.tedu.entity;
/*
* 体现java中封装,
* 私有key不允许直接访问(隐藏)
* 只能通过get和set方法进行操作
*/
public class Phone {
private String key;
//自动产生get和set方法,里面会有this,含义
public String getKey() {
return key;
}
public void setKey(String key) {
//this代表当前对象,this.key代表属性,key代表参数
this.key = key;
}
}
package test;
import cn.tedu.entity.Phone;
public class TestPhone {
public static void main(String[] args) {
//1.创建实例
Phone phone = new Phone();
//2.调用set方法设置值
phone.setKey("188");
//3.调用get方法获取,打印
System.out.println( phone.getKey() );
}
}
package cn.tedu.entity;
import java.util.Date; //必须选择util包下的,不能选择sql包下的,否则报错
public class Person {
//私有属性(字段)都习惯使用包装类型
private String name;
private Integer age;
private Date birthday; //日期类型
private String address;
//产生它的gets/sets方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override //重写,重新父类Object.toString方法
public String toString() {
return "Person [name=" + name + ", age=" + age + ", birthday=" + birthday + ", address=" + address + "]";
}
}
package test;
import java.util.Date;
import cn.tedu.entity.Person;
public class TestPerson {
public static void main(String[] args) {
//1.创建对象
Person person = new Person();
//2.设置值,初始化,设置是没有顺序的(自由)
person.setName("陈晨");
person.setAge(12);
person.setBirthday(new Date()); //当前日期
person.setAddress("北京中关村");
//3.访问,打印。覆盖它的toString() 自动产生
System.out.println(person.toString());
}
}
继承 inheritance
c语言的继承非常强大,它支持多继承(爸、妈。。。)有风险,非常难控制,继承层级过多后,非常难知道继承来自谁
java语言简化c语言,不支持多继承,只支持单继承。安全。
java中继承的类,称为超类superClass(),也称为父类,有时叫基类。
它虽然不支持多继承,但是支持多级继承,多重继承。B继承A,C继承B,也就是说C间接继承A
爸继承了爷财产,我继承爸财产,也就是说,我最终继承了爷爷财产
java有两种继承方式
父类(类 class)使用 extends 关键字(继承)
父类(接口 interface) 使用 implements 关键字(实现)
继承的语法
package cn.tedu.entity;
//代表父类
public class Dad {
private Double money = 100.0; //遗产
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
package test;
import cn.tedu.entity.Son;
public class TestSon {
public static void main(String[] args) {
//需求:看儿子有多少钱?
//1.创建子类
Son son = new Son();
//2.通过子类去调用父类方法
//子类没有,就去访问父类的方法
System.out.println(son.getMoney());
}
}
没有继承代码怎么写?
需求:动物类,老虎 tiger(吃eat()、跑run()),鹰 eagle(吃eat()、飞fly())
类有共性eat(),个性,tiger.run()跑、eagle.fly()飞
怎么在java中体现上面的内容。
package cn.tedu.entity;
//老虎类
public class Tiger {
//共有的方法
public void eat() {
System.out.println("吃肉肉");
}
//个性的方法
public void run() {
System.out.println("陆地之王,跑的快");
}
}
package cn.tedu.entity;
//老鹰类
public class Eagle {
//共有的方法
public void eat() {
System.out.println("吃肉肉");
}
//个性的方法
public void fly() {
System.out.println("天空之王,飞的高");
}
}
没有使用继承时,代码有冗余,每个类中都有这部分公用的代码,如果代码需要修改,就被迫得修改多处。
它的缺点。
可以使用继承来修改它,改造它!
1)创建父类,公用的代码写 Animal动物类,eat()
2)使用extends继承,去掉重复代码 Tiger extends Animal,Eagle extends Animal。子类可以调用父类的方法
父类的方式
package cn.tedu.entity;
//把老虎和老鹰共性的内容提取到这个类中
public class Animal {
//共有的方法
public void eat() {
System.out.println("吃肉肉");
}
}
package cn.tedu.entity;
//老虎类,继承父类,动物类
public class Tiger extends Animal{
//个性的方法
public void run() {
System.out.println("陆地之王,跑的快");
}
}
package cn.tedu.entity;
//老鹰类,继承父类,动物类
public class Eagle extends Animal{
//个性的方法
public void fly() {
System.out.println("天空之王,飞的高");
}
}
package test;
import cn.tedu.entity.Eagle;
import cn.tedu.entity.Tiger;
public class TestAnimal {
public static void main(String[] args) {
//老虎类
//1.创建对象
Tiger tiger = new Tiger();
//2.调用对象共性和个性方法
tiger.eat(); //继承父类方法
tiger.run(); //本类个性方法
//老鹰类
Eagle eagle = new Eagle();
eagle.eat(); //继承父类方法
eagle.fly(); //本类个性方法
}
}
接口方式继承
package cn.tedu.entity;
//水果类,它是一个接口
/*
* 接口和实现类它不同的地方,实现类中是有实现代码的eat()方法
* 但是接口中没有,它只有方法的定义,没有方法的实现
* 也就是说,接口只用来规范你要有什么方法,但是方法子类去具体实现
*/
public interface IFruit {
public void eat(); //只有放到的定义(声明),没有实现
}
package cn.tedu.entity;
//接口的实现类
//它要实现接口的所有的方法和自己个性方法
public class AppleImpl implements IFruit{
@Override //重写接口的方法,实现接口的方法
public void eat() {
System.out.println("水果可以吃");
}
//个性方法自己加
public void cut() { //削皮
System.out.println("苹果削皮");
}
}
package cn.tedu.entity;
//实现类,实现水果接口
public class BeanImpl implements IFruit{
@Override //实现接口定义方法
public void eat() {
System.out.println("吃豆豆");
}
public void grow() { //添加个性的方法
System.out.println("种豆豆");
}
}
package test;
import cn.tedu.entity.AppleImpl;
import cn.tedu.entity.BeanImpl;
import cn.tedu.entity.IFruit;
public class TestFruit {
public static void main(String[] args) {
//1、创建对象:接口 实例名=new 子类();
//AppleImpl apple = new AppleImpl();
//只能调用接口中声明的方法
IFruit apple = new AppleImpl();
//2、调用
apple.eat();
IFruit bean = new BeanImpl();
bean.eat();
}
}
两种继承方式的区别
多态 polymorphism
多态:同一个对象同一个方法表现状态不同。
水,绝对零度下-273°(固态),平时温度(液态)
java在多时它一般有一个前提,继承之后发生。
1)子类覆盖Object的toString()方法,重写override,把父类的方法重新定义,运行时多态
2)基本类型的判别 int、byte、short。。。,相同的方法名,但是它的参数类型不同,重载overload,编译器多态
重写,运行时多态
package cn.tedu.entity;
//创建学生类,重新它的toString方法
public class Student {
//私有属性
private Integer sno; //学号
private String name; //学生姓名
private String school; //毕业学校
private String address; //地址
//生成get和set方法
public Integer getSno() {
return sno;
}
public void setSno(Integer sno) {
this.sno = sno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student [sno=" + sno + ", name=" + name + ", school=" + school + ", address=" + address + "]";
}
}
package test;
import cn.tedu.entity.Student;
public class TestStudent {
public static void main(String[] args) {
Student student = new Student();
student.setSno(100);
student.setName("王琪");
student.setSchool("清北");
student.setAddress("五道口");
//同样是一个toString方法,但由于重写后,和重新前表现形式不同,多态
//什么时候确定呢?父类和子类都有toString方法,此时运行到这里,那调用哪个方法呢?
//上面是动态选择的,所以称为运行时多态。
System.out.println(student.toString()); //最终调用子类方法,就近原则
}
}
重载,编译期多态
package test;
//需求:给定某个8基本类型,声明一个变量,打印出变量的类型
public class TestType {
//重载,方法名相同,参数类型不同
public void println(byte x) {
System.out.println("byte类型");
}
public void println(short x) {
System.out.println("short类型");
}
public void println(int x) {
System.out.println("int类型");
}
public void println(long x) {
System.out.println("long类型");
}
public void println(float x) {
System.out.println("float类型");
}
public void println(double x) {
System.out.println("double类型");
}
public void println(char x) {
System.out.println("char类型");
}
public void println(boolean x) {
System.out.println("boolean类型");
}
public static void main(String[] args) {
//double x = 100.0;
//char x = 'a';
boolean x = true;
// 1.创建类对象实例
TestType tt = new TestType();
// 2.调用方法,设置值
// 编译时,x已经知道它的类型了,称作编译期多态
// 多态,同一个方法同一个参数,但是结果却不同
tt.println(x); // 强制设置100为字节类型
}
}
以上是关于java小白训练营day06-OOP:面向对象+封装+继承+多态的主要内容,如果未能解决你的问题,请参考以下文章
java小白训练营2109-day03-数据结构:基本类型+包装类型+数组+对象