第五章 第二节 面向对象(面向对象的三大特性、抽象类和接口)

第五章 第二节 面向对象(面向对象的三大特性、抽象类和接口)

1.面向对象的三大特性

面向对象的三大特性:封装、继承、多态

抽象就是指,将对象的特性抽象为属性,对象的行为抽象成方法。

1.1封装

编写类时,将功能相同的或相近的代码写到一个类中,这就是一个封装的过程。(比如之前我们写的Student类,将学生的姓名、学号、性别、年龄等写到一个类中,这就是封装)

​ 在Java中为了更好地保护类不被外部干扰,还需要使用JavaBean的方式编写类。

1)类的属性使用private修饰

在这里插入图片描述

如上图所示,相当于就是把Student的属性全部暴露在了外面,外面能进行直接修改。
从外部能100%的控制内部。但是外部如果能修改容易出现输入错误—>使用private修饰,
则不能从外部更改使用了:如下图:已经定义成private的age只能在类的内部访问,
在类的外部访问就会报错。

在这里插入图片描述

既然private修饰的内容只能在内部访问,那么我们如何在内部进行更改?在外部如何访问?---->给外部一定的
权限

2)为属性添加公共的Get和Set方法

Get方法:获取属性的值;Set方法:设置属性的值;

在内部的Set方法里面可以添加限定条件,如下图所示:在外部只需要进行调用Set方法进行传入参数即可,并

且如下图所写的内部setAge方法会根据条件进行判断再确定是否进行修改设置值的操作。

在这里插入图片描述

如果想在外部输入age:如下图所示,调用getAge方法:

在这里插入图片描述
总结:

广义上的封装:编写类的过程就是一个封装的过程。

狭义的封装:隐藏类的实现细节,更好地保护类的内部。

封装的步骤:

1) 将所有的属性私有化,使用private关键字修饰。

2) 为所有的属性提供公共的get和set方法。

Eclispe提供了快速生成get和set方法的生成器。

还可以借助第三方的工具,lombok。

右键Source或者上面菜单Source,选择Generate Getters and Setters,在弹出的窗口右侧选择select all;

再点击ok即可。就会自动添加对应的get和set方法。

在这里插入图片描述
在这里插入图片描述

如下图封装的完整代码示例:

在这里插入图片描述

高内聚,低耦合

1.2继承

继承是指类与类之间的关系,也就是泛化。继承是类与类之间最密切的一种关系,是很强的一种关系。

在定义一个类时,可以使用extends关键字指定它的父类。

语法:

public class 子类名 extends 父类名 {
}
被继承的类就是父类,基类(base class),超类(super class)。

继承父类的类就是子类,派生类,扩展类。

1.2.1继承的特性

继承是为了代码复用。

1) 子类会继承父类的所有属性和方法,但是私有的不会继承。

比如下图中父类定义为:Person

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在子类中我们没有定义name属性,但是可以用,是从父类Person里面继承过来的

2) 子类可以扩展只属于自己的属性和方法。

在这里插入图片描述

3) 子类还可以重写父类的属性和方法,覆盖父类的属性和方法。

注意:
1)子类会继承父类的私有属性和方法,只是不能直接访问(可以通过Set、Get方法间接访问)
2)子类不会继承父类的构造方法,但是调用子类构造方法时,会先调用父类的构造方法。

1.2.2隐藏属性

如果子类中声明与父类中名字相同的属性,父类的属性将被隐藏,子类对象只能访问子类中重新定义的属性。

隐藏属性类型可以不同。
在这里插入图片描述
在这里插入图片描述

1.2.3方法的重写

方法的重写也叫方法的复写,也叫方法的覆盖。

在继承关系下,子类中出现了和父类方法名以及参数列表都相同的方法,这种情况子类重写了父类的方法。

注意:

1) 子类重写方法的返回值类型不能大于父类方法的返回值类型。

2) 子类重写方法的权限修饰符不能小于父类方法的权限修饰符。

3) 私有的方法不算重写。

4) 子类重写方法时,可以使用@Override注解检查是不是重写的父类方法。

1.3多态

多态:多种形态
多态是指相同或近似的代码,在执行时表现出不同的形态,调用不同的方法。

在Java中,多态有两种体现形式,编译时多态和运行时多态。(方法的重载、方法的重写)

1.3.1编译时多态

在代码编译时,决定调用哪个方法。主要体现方式是方法的重载。
方法的重载:
在一个类中,出现了方法名相同,但是参数列表不同的方法。

重载方法在调用时,由实参的数据类型决定调用哪个方法。
方法的确定是代码编译时就可以确定的

因方法的重载带来的多态,称为编译时多态。

1.3.2运行时多态

代码在运行时,才能决定应该调用哪个方法。主要体现方式是方法的重写。

方法的重写:

在继承关系下,子类中出现了和父类方法名以及参数列表(参数的数据类型、顺序、数量)都一样的方法,子类重写了父类的方法。

注意:
1)子类方法的参数数量,类型和顺序必须与父类方法一样
2)子类方法的参数名可以与父类不一样
3)子类方法的返回值类型必须小于等于父类方法的返回值类型,如果是引用数据类型必须一样,引用数据类型子类方法的返回值类型可以是父类方法返回值的子类(小于),等于也行。
4)private的方法不能被子类重写
5)子类方法的权限修饰符必须大于等于父类方法的权限修饰符。

上转型对象: 子类创建的对象,保存在父类类型的变量中。

上转型对象的特点:

1) 上转型对象只能调用父类声明的属性和方法。(父类中定义的方法和父类继承来的方法)

2) 上转型对象在调用子类重写的方法,执行的是子类中的方法。

这种多态,只有在代码运行时才能确定调用哪个,称为运行时多态。
在这里插入图片描述
在这里插入图片描述
总结:我们在执行方法时,是站在对象类型的角度上执行的;在调用时,是站在变量类型的角度上进行调用的。

1.4练习

public class Demo02 {
public static void main(String[] args) {
A a = new A(); // a是A类型,值也是A类型
A b = new B(); // b是A类型,值是B类型,b是一个上转型对象
C c = new C(); // c是C类型,值也是C类型

	// 重载方法在调用时,由实参的数据类型决定调用哪个方法。
	// 上转型对象只能调用父类声明的属性和方法。
	// 上转型对象在调用子类重写的方法,执行的是子类的方法。
	// a 对象可以调用哪些方法
	// A.show(A)
	// A.show(B)
	a.show(a);	// 参数a的类型是A,A.a
	a.show(b);	// 参数b的数据类型是A, A.a
	a.show(c);	// 参数c的类型是C, B类更接近,A.b

	// b是个上转型对象 b只能调用父类中声明的方法
	// b对象可以调用的方法, 
	// A.show(A)
	// A.show(B) => B.show(B)
	b.show(a);	// 参数a的类型是A, A.a
	b.show(b);  // 参数b的数据类型是A, A.a
	b.show(c);  // 参数c的类型是C, B类更接近, B.b

	// c可以调用什么方法
	// A.show(A)
	// A.show(B) => B.show(B)
	// B.show(C)
	c.show(a);	//参数a的类型是A, A.a
	c.show(b);	//参数b的数据类型是A, A.a
	c.show(c);	//参数c的类型是C, B.c
}

}

class A {
public void show(A a) {
System.out.println(“A.a”);
}
public void show(B b) {
System.out.println(“A.b”);
}
}

class B extends A {
public void show(B b) {
System.out.println(“B.b”);
}
public void show(C c) {
System.out.println(“B.c”);
}
}

class C extends B {

}
在这里插入图片描述

2.抽象类
2.1抽象类

什么是抽象类?

抽象类是一特殊的类,被abstract关键字修饰的类就是抽象类。

在Java中,有些类不适合创建对象,这时可以把类定义成抽象类。

抽象类不能创建对象,但是作为父类使用。如下图所示,抽象类创建对象会报错:

在这里插入图片描述
抽象类可以像普通类一样,有属性、方法、构造器、块和静态块、内部类,还可以继承父类,实现接口。

抽象类的使用必须依赖于它的子类。

public abstract class 类名 {
   类体;
}
2.2抽象方法

被abstract关键字修饰的方法就是抽象方法 。抽象方法只有方法的定义,没有方法的实现(没有方法体)。抽象方法不能有方法体,结尾必须以;结束。如下图:
在这里插入图片描述

抽象方法必须由子类重写/实现。

修饰符 abstract 方法名(参数列表);
2.3抽象类与抽象方法的关系

1)抽象类可以拥有类所拥有的一切,包括:属性,方法,构造方法等;

抽象类可以有抽象方法,也可以没有。

2) 有抽象方法的类必须是抽象类。

抽象方法是一个不完整的方法,抽象类可以包含抽象方法,抽象类也就是一个不完整的类,由不完整的类创建对象,行为就是不确定的,Java中不允许出现这种对象。因此抽象类不能创建对象。

为什么还要有抽象类和抽象方法?

在抽象过程中,有些类的行为是不确定的,这些行为不能有具体的实现,因此必须依赖抽象方法进行描述。

有面向对象的过程中,有些类就不应该直接创建对象,这样的类就应该定义成抽象类。

比如:教学管理系统,在这个系统中包含两种角色学生和老师,学生和老师存在共性,都有姓名,性别,就需要有一个父类人管理这些共性,同时实现代码复用。人是不能直接创建对象的。

抽象类的子类有两个选择:

1) 实现抽象类中的所有抽象方法,子类就可以是一个普通类

2)如果没有实现所有的抽象方法(会继承父类方法),子类必须是一个抽象类。

接口的实现类类似。

3.接口

接口是一种比抽象类更抽象的数据类型。

接口的特点:

1) 接口中的属性,默认使用public static final修饰,也就是公共的静态常量。

2) 接口中的方法,默认使用public abstract修饰,也就是公共的抽象方法。

3) 接口也是不能创建对象的。

接口语法:

public interface 接口名{
     静态常量;
     抽象方法;
}

接口不能创建对象,因此接口的使用必须依赖于它的实现类。

修饰符 class 类名 implements 接口名1, 接口名2{
    类体
}

注意:

Java中一个类最多只能有一个直接父类,单继承。
(理解:门 防火门 防火防盗门)
可以让一个类同时实现多个接口来解决单继承的问题,称为多实现。

一个接口也可以继承另外一个接口,使用extends

接口也可以继承父接口的所有方法,而且也是单继承。

jdk1.8中新特性:

1)函数式接口:接口中只有一个抽象方法
在这里插入图片描述

2)允许接口中有静态方法

3)允许接口中有默认方法

在这里插入图片描述

注意:
接口的实现类,要么实现接口中所有的抽象方法,要么实现类就只能是一个抽象类。

3.1为什么要使用接口

在Java中一个类最多只能有一个直接的父类,这叫类的单继承

一个类可以同时实现多个接口,这叫多实现,多实现是为了弥补单继承的缺陷。

接口也可以继承,接口的继承是多继承的。

面向接口编程

3.2面试常见问题
  1. 抽象类与接口的异同??

相同点:抽象类和接口都不能创建对象,抽象类和接口都可以拥有抽象方法。

不同点:

1) 抽象类是类,接口是接口,它们是不同的数据类型。

2) 抽象类可以包含属性,方法,构造方法,接口只能拥有静态常量和抽象方法。

3) 抽象类的使用依赖于它的子类,子类是使用extends关键字继承,接口的使用依赖于它的实现类,使用implements关键实现接口。

4) 类的继承是单继承,接口的继承是多继承。

  1. JDK8的新特性

1) 函数式接口:在一个接口中,如果只包含一个抽象方法,这个接口就叫函数式接口。

@FunctionalInterface 检查函数式接口

2) 接口静态方法:在接口中可以定义静态方法,可以拥有方法体。

3) 接口默认方法:接口中可以使用default修饰方法,默认方法可以有方法体,实现类可以选择重写也可以不重写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.又是新的一天.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值