java小白训练营2109-day06-OOP:面向对象+封装+继承+多态
Posted 长安紫薯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java小白训练营2109-day06-OOP:面向对象+封装+继承+多态相关的知识,希望对你有一定的参考价值。
文章目录
面向对象
面向过程和面向对象的区别?
编程思想
面向过程:关注完成一个需求,代码实现步骤,每一步都完成,整个需求就实现。
面向对象:关注实体 entity,特征(属性)+行为(方法),建模(建立模型),然后在一步步的实现(步骤)
案例:把大象装入冰箱
面向过程思考的方式:步骤
第一步:把冰箱门打开,
第二步:把大象放入,
第三步:把冰箱门关上
(步骤)
面向对象思考的方式:实体+步骤
实体(从描述中挑名称)大象和冰箱
大象:特征(巨大、鼻子长、很重、…)行为(吃、跑、洗澡…)
冰箱:特征(门、电、容积…)行为(制冷、存储、开门、关门…)
(步骤)
案例:我去超市买葡萄、水饺、薯片、香蕉
面向过程:
第一步:出门,去超市
第二步:找葡萄、找水饺,买
第三步:回家
面向对象:
实体:葡萄、水饺、超市的所有商品!!!!!(香蕉、包子、薯片)
第一步:出门,去超市
第二步:找葡萄、找水饺、薯片、香蕉,买
第三步:回家
需求变更,(用户)
用户至上!ipad
实际开发,半面向对象,半面向过程,结合来实现具体的代码
面向对象的三大特征
封装、继承、多态、(抽象)
封装 encapsulation
作用:包装,不能看到它的内部结构,也不能了解其内部运行机制。封装后,好处使用起来简单,不需要知道它运行机制,照样使用。隐藏起来,让使用者更加方便简易。
String api ,这些方法你知道它怎么实现吗? 日常使用者是不知道的,也不需要知道。日常开发者知道其特性,能正确使用即可。toUpperCase() 特性外在表现,大写。
包装类型,它是引用类型,打印时不是,重写了toString方法,重写了hashcode(特殊处理)
封装案例,实体对象
Person实体
1)私有属性 private,对应每个私有属性
2)两个方法 getName() 获取,setName() 设置(eclipse直接自动生成)
上面的过程,私有是属性,它无法直接进行访问,必须通过新的get和set进行访问,特别是set
p.name =“tony”;
p.setName(“tony”);
setName内部在干什么,调用者它是不知道的,这个就是封装,隐藏实现细节。
package cn.tedu.entity;
/*
* 实体类:
* 1)一堆私有属性,见名知意
* 2)每个属性都有get和set方法
*/
public class Person {
private String name; //姓名
private Double money; //薪水
public String getName() {
return name;
}
public void setName(String name) {
//name参数
//this.name 属性,成员变量 this代表当前类
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
package cn.tedu.entity;
/*
* 实体类:
* 1)一堆私有属性,见名知意
* 2)每个属性都有get和set方法
* 3)不是必要,测试(调试)toString()
*/
public class Person {
private String name; //姓名
private Double money; //薪水
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override //注解,重写,覆盖父类Object.toString()方法
public String toString() {
return "Person [name=" + name + ", money=" + money + "]";
}
}
package test;
import org.junit.Test;
import cn.tedu.entity.Person;
public class TestPerson {
@Test
public void person() {
//1. 创建对象实例
Person person = new Person();
//2. 设置属性值
person.setName("陈晨");
person.setMoney(10000.0);
//3. 获取属性值进行打印
System.out.println(person.getName());
System.out.println(person.getMoney());
//4. 打印对象不是地址,而是想打印它的所有的内容
System.out.println(person);
//打印对象实质是调用对象的toString方法,如果对象没有写这个方法,它会调用父类的toString();
//为什么它不调用父类的方法,而调用自己的方法呢? 方法名相同是调用原则:就近原则
System.out.println(person.toString());
}
}
利用eclipse 自动生成get和set方法,以及toString()方法
继承 inheritance
java中继承和其他语言不同的,它提供两种方式
1)继承 extends 只能单继承,安全性高不易出错
2)实现 implements 可以实现多个接口,它的类也称为实现类
为什么需要类继承?
继承的好处是,可以减少相同的代码(冗余),当需要变化时,只需修改一处,所以调用的地方就都更新了。
package cn.tedu.entity;
//水果类
public class Fruit {
public void eat() {
System.out.println("水果可以吃");
}
}
package cn.tedu.entity;
//苹果类,继承父类,父类的公用的方法就直接可以调用
public class Apple extends Fruit{
}
package cn.tedu.entity;
//梨类,代码冗余了?
public class Pear extends Fruit{
}
接口的实现方式
需求:
动物,老虎和兔子,他们都吃东西(共性)老虎吃肉肉,兔子吃草草
package cn.tedu.entity;
//接口,定规矩,定要求
//所有的类都得实现eat()方法
public interface Animal {
//不实现,只定规矩
//这里只定义规矩,子类去实现具体的代码
public void eat(); //这里只是一个方法的定义,没有方式的实现代码
}
package cn.tedu.entity;
//老虎实现类
public class Tiger implements Animal{
@Override
public void eat() {
System.out.println("老虎吃肉肉");
}
}
package cn.tedu.entity;
//兔子实现类,遵守规矩,implements 接口
//它必须实现Animal接口中定义方法,必须写类的实现的代码
//The type Rabbit must implement
//the inherited abstract method Animal.eat()
public class Rabbit implements Animal{
@Override //覆盖,重写,有没有都可以,它是提示你覆盖父类的方法
public void eat() {
System.out.println("兔子吃草草");
}
}
package test;
import org.junit.Test;
import cn.tedu.entity.Animal;
import cn.tedu.entity.Apple;
import cn.tedu.entity.Rabbit;
import cn.tedu.entity.Tiger;
public class TestAnimal {
@Test
public void animal() {
//类的写法
//格式:类名 实例名 = new 类名();
Apple apple = new Apple();
//接口的写法
//格式:接口名称 实例名称 = new 实现类名称();
//Cannot instantiate the type Animal 接口animal是不能实例化
//Animal tiger = new Animal();
Animal tiger = new Tiger();
tiger.eat();
Animal rabbit = new Rabbit();
rabbit.eat();
}
}
两种继承方式比较
多态 polymorphism
需求:人Person,喂小动物 feed( who )
现在有:老虎,兔子
person.feed(老虎)
person.feed(兔子)
需求变更:狗、猫
person.feed(狗)
person.feed(猫)
增不能写个通用的,代码量急剧降低,如果在有新的动物,person.feed(new)
person.feed(Animal)
package cn.tedu.entity;
/*
* 实体类:
* 1)一堆私有属性,见名知意
* 2)每个属性都有get和set方法
* 3)不是必要,测试(调试)toString()
*/
public class Person {
private String name; //姓名
private Double money; //薪水
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override //注解,重写,覆盖父类Object.toString()方法
public String toString() {
return "Person [name=" + name + ", money=" + money + "]";
}
//不通用的方式,有几个动物就得写多个个代码,代码量非常的大
//喂老虎
public void eat(Tiger tiger) {
tiger.eat();
}
//喂兔子
public void eat(Rabbit rabbit) {
rabbit.eat();
}
//通用的结构,使用接口作为参数
//如果有新的动物扩充,此时这里的代码无需修改
public void eat(Animal animal) {
//它的参数不能是接口,但是接口的子类
//实现类,实现类中写了具体代码
animal.eat();
}
}
package cn.tedu.entity;
//猫类,实现Animal它的接口,必须实现Animal定义的所有的方法
public class Cat implements Animal{
@Override
public void eat() { //遵循Animal定义eat方法,守规矩
System.out.println("猫吃小鱼");
}
}
package test;
import org.junit.Test;
import cn.tedu.entity.Animal;
import cn.tedu.entity.Cat;
import cn.tedu.entity.Person;
import cn.tedu.entity.Rabbit;
import cn.tedu.entity.Tiger;
public class TestPerson {
@Test
public void person() {
//1. 创建对象实例
Person person = new Person();
//2. 设置属性值
person.setName("陈晨");
person.setMoney(10000.0);
//3. 获取属性值进行打印
System.out.println(person.getName());
System.out.println(person.getMoney());
//4. 打印对象不是地址,而是想打印它的所有的内容
System.out.println(person);
//打印对象实质是调用对象的toString方法,如果对象没有写这个方法,它会调用父类的toString();
//为什么它不调用父类的方法,而调用自己的方法呢? 方法名相同是调用原则:就近原则
System.out.println(person.toString());
//不通用的方式的调用,创建参数
Tiger tiger = new Tiger();
person.eat(tiger);
Rabbit rabbit = new Rabbit();
person.eat(rabbit);
//通用的方式的调用,多态:同一个Animal但是最终结果是不同的
Animal tiger2 = new Tiger();
person.eat(tiger2);
Animal rabbit2 = new Rabbit();
person.eat(rabbit2);
Animal cat = new Cat();
person.eat(cat);
}
}
小结
1)java面向对象
a. 面向过程:关注代码编写步骤,解决每个步骤中技术难点,使用工具代码实现即可
b. 面向对象:关注实体创建(建模)特征(私有属性)公有的get和set方法,eat()业务方法,然后咱步骤实现
c. 面向切面:AOP 它是面向对象的有益补充,但是必须现有面向对象,才有面向切面
d. 面向服务:SOA,SOA最佳实践:微服务 SpringCloud Alibaba
2)面向对象这种编程思想为何会胜出面向过程?
需求变更(满足一定的代码变化)
取个平衡点,编程要适度(超市不可能把所有的商品建模,可以超出当前的需求,把常用的都建模)
主流的开发思想是使用面向对象,java,c++,python
3)面向对象概念:三大特征
a. 封装:被隐藏起来,开发者需要知道的内容就少了,代码也更加少,好处开发者容易学习
b. 继承:两种实现方式
b1:extends 继承类,公用代码都写在父类中,代码量急剧降低,每个子类无需写相同重复代码,复用
b2:implements 实现接口,没有少写代码,它的作用就是定义规范,所有的子类都必须遵守
c. 多态:同一个事务可以展现出不同的结果 Animal tiger.eat 吃肉肉,rabbit.eat 吃草草
好处,代码通用,向后兼容 Tiger,Rabbit
4)封装具体的实现
a. 创建实体类 entity
b. 一堆的私有属性(特性),外部不能直接访问 private String name;
c. 一堆的get和set方法来调用(行为)getName()、setName();
d. 一堆业务的方法(行为) eat(), play()。。。
5)类的继承
a. java单继承,就想继承多个类?多级继承,爷爷-父亲-我,没有c语言多继承灵活,但安全,不易出错,出错好找的问题的所在类
b. 把公用的代码就写在父类中
c. 怎么表达是当前的类 this,还是父类 super?
d. 子类调用 Fruit 水果是父类,Apple是子类,怎么调用父类方法
d1)声明它们之间的关系,继承关系:class Apple extends Fruit
d2)调用 Apple apple = new Apple(); apple.eat(); 执行时,先到本类查找,没有eat方法,它就去父类查找方法eat()
好处:复用代码 apple可以调用fruit.eat(),pear可以调用fruit.eat()
6)接口的实现
a. 定义接口,只写方法的定义。规定方法返回值,方法名称,方法的参数
b. 实现接口 Animal tiger = new Tiger(); 关系表达 class tiger implements Animal;
c. 在tiger就必须实现Animal接口中所有的方法定义
好处:规范代码,实现向后兼容,程序就方便扩展 JDBC
主流开发方式提倡,面向接口开发!
7)类和接口的本质差异
a. 类使用class修饰,接口使用 interface修饰
b. 类中内容都必须实现,接口中没有实现的代码
c. 类是可以被extends继承的,任何类都可以有子类;接口实现接口(多级)
d. 类干活,接口不干活
8)多态
a. 同一个类,表现出不同的结果
package test;
public class TestMain {
public static void main(String[] args) {
int i = 100; //整数
String s = “abc”; //字符串
//运行时多态
System.out.println(i);
System.out.println(s);
}
}
以上是关于java小白训练营2109-day06-OOP:面向对象+封装+继承+多态的主要内容,如果未能解决你的问题,请参考以下文章