Java学习 11.19
1.1 案例一 : 人类喂狗
需要完成一个功能: Dog类有一个eat函数,人类有一个feed函数 ,人类的feed函数能传递狗对象并且调用其eat函数
public class People {
public void feed(Dog dog){
dog.eat();
}
}
public class Dog {
public void eat(){
System.out.println("狗爱吃肉");
}
}
public class JavaTest {
public static void main(String[] args) {
Dog wangcai = new Dog();
People zhangsan = new People();
zhangsan.feed(wangcai);
}
}
问题: 狗为什么不自己吃?
因为我们这个案例 是模拟后期的一种场景,一个类要使用另一个类的对象, People 需要使用Dog对象 调用Dog对象的函数
这是后面我们学习Spring的时候 依赖注入DI的操作
![]()


函数中参数传递的时候 基本类型传参 和 对象类型传参 有什么不同? 基本类型是传值 对象类型是传址 ---- 大错特错
无论是什么 都是传递的引用地址
1.2 案例2: 人类喂猫
需要我们创建一个猫类 添加eat函数,人类也需要喂猫。
public class Cat {
public void eat(){
System.out.println("猫爱吃鱼");
}
}
此时让zhangsan去喂猫,发现报错,因为参数类型不匹配 feed(Dog dog) 此时传递的是Cat类型 。
public class People {
public void feed(Dog dog){
dog.eat();
}
public void feed11111111(Cat cat){
cat.eat();
}
}
现在喂狗 用 feed 喂猫用 feed1 此时我们发现如果动物再多一点 我们需要不同的动物 使用不同的函数 很麻烦
所以我们可以使用函数的重载
public class People {
public void feed(Dog dog){
dog.eat();
}
public void feed(Cat cat){
cat.eat();
}
}
此时调用的时候 我们不管什么动物 只需要调用feed就行
public class JavaTest {
public static void main(String[] args) {
Dog wangcai = new Dog();
Cat kate = new Cat();
People zhangsan = new People();
zhangsan.feed(wangcai);
zhangsan.feed(kate);
}
}
1.3 人类喂猪
需要创建一个Pig类,也有eat函数,人类也需要喂猪。
这个操作就是创建一个Pig类
public class Pig {
public void eat(){
System.out.println("猪爱吃饲料");
}
}
人类要喂猪,人类需要再重载一个feed函数 参数类型是Pig类型
问题就来了 : 这样操作能行,但是有问题,后续如果还有新动物,人类就需要不断的去重载
这样的代码 我们称之为 高耦合(我们的代码联系太密切 牵一发而动全身)
高内聚低耦合,是软件工程中的概念,是判断软件设计好坏的标准,主要用于程序的面向对象的设计,主要看类的内聚性是否高,耦合度是否低。目的是使程序模块的可重用性、移植性大大增强。通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事,它描述的是模块内的功能联系;耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
优秀的代码: 低耦合 高内聚
所以我们需要一个方案 来降低耦合,就目前我们的案例而言:添加新动物 人类不需要重载 还能正常喂养
1.4 创造了这样一个语法来解决问题
此时造了这样一个语法:
public class Haha {
public void eat(){
System.out.println("你好世界");
}
}
public class Dog extends Haha{
多态: 多种状态 运行状态和编译状态
Haha d = new Dog();
d 编译的时候 是Haha 运行的时候是Dog
1.5 出现了一个新问题
此时我们将People 和 动物们解耦了,但新问题:
1 Haha能否被创建对象?合适不?
能 不合适,因为没有Haha这种动物,Haha存在是为了作为其他动物的父类,这样能产生多态,从而解耦
也就是说 Haha这个类 不是为了创建对象而存在的 并且也不能被创建对象
2 Haha的eat可以不写吗?为什么?
不能 因为虽然没有用 但是不写编译不过去。也就是说必须写 但是又不会被调用
所以 函数声明是有用的:为了让编译通过 函数的体是没有用的因为写什么都不会被调用。
3 Dog Pig Cat 不写eat能行么?合适吗?
可以 不合适,不写就去调用父类,但是需求是每个类都要有自己的eat
总结以上三点:我们需要弄一个新语法
1 某个类不能被new对象
2 函数可以只声明 不用写方法体
3 子类必须写要求写的函数
所以java的开发者 就造了一个关键字 只要添加这个关键字 就能实现我们想要的效果 并且给其命名为 : 抽象
1.6 抽象解决当前的问题
public abstract class Haha {
public abstract void eat();
}
1.7 抽象的语法规则
1 abstract添加到类上面称之为抽象类
2 抽象类不能new对象
3 抽象类有构造函数 [构造函数就是与new连用用来创建对象 但是抽象类不能被new对象 构造函数存在的意义是什么呢?为了子类继承的时候 super() ]
4 抽象类中可以有抽象函数 也可以有成员变量 普通函数 静态变量 静态常量等内容
----- 抽象类和普通类相比 在于抽象类可以添加抽象函数 但是不能new对象
5 abstract添加到方法上面称之为抽象方法
6 抽象方法一定是在抽象类中(接口)
7 抽象方法不写也不能写方法体
8 抽象方法必须由子类负责重写或者子类也是抽象的
9 抽象方法不能和无法重写的关键词连用 private final static
java面向对象特征: 封装 继承 多态 抽象 接口

浙公网安备 33010602011771号