封装、继承、多态、接口
1.封装
封装,就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。
目的:增强安全性和简化编程,使用者可以不用了解具体的实现细节,只需奥通过外部接口,以特定的访问权限来使用类的成员。
1.1Java的封装
广义来说:一切公共代码的抽取都可以叫封装。
一般体现在公共方法的封装。工具类
狭义来说:隐藏对象的属性和实现细节
- 将属性私有化,使用private关键字修饰。
- 为使用private关键字修饰的属性添加getter、setter方法。通过get、set方法来操作属性。
- 在setter方法中,添加数据校验。
作用: 保护属性的有效性。
2.继承
继承是面向对象中的一个概念,可以使子类具有父类的非私有的属性和方法或者可以重新定义、追加属性和方法等。
继承就是子类继承父类的特征和行为,使得子类对象实例具有父类的属性和方法,或从父类继承方法,使得子类具有父类相同的行为。
目的: 提升代码的可重用性、可以扩展功能、方便维护。
Java是单继承,只能有一个父类。
关键字: extends
2.1方法重写@Override注解
在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不 需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一 定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
方法重写和方法重载的区别:
重载:发生在同一个类中,方法名相同,参数列表不同,不考虑返回值。
重写: 发生在父子类中,子类继承父类的方法,方法名相同,参数也相同,但是实现方法体不同。
重写:
- 必须保证父子类中重写的方法,方法名相同,参数列表相同
- 子类方法的返回值必须小于或等于父类方法的返回值范围。
- 子类方法的权限必须要大于等于父类方法的权限(不包括 private)
- 子类重写方法异常声明必须是父类的异常或子级异常
- 私有的不能被继承
重写
toString()方法
- 任何类都是Object类的直接子类或者间接子类,在Object类中有一个toString()方法。
当输出一个对象时,先调用当前类的toString()方法,如果当前类没有toString() , 就去找当前类的父类,看是否有toString()方法,如果过父类也没有,就去找Object类 中的toString()方法并运行。
2.2super关键字,this关键字
作用:如果子类既想使用自己的方法,又想调用父类的成员变量和成员方法,需要通过super关键字。
super关键字使用:
- 在子类的成员方法中访问父类的成员变量和方法
- 在子类的构造方法中访问父类的构造方法。
2.3继承中构造方法的特点
- 构造方法不能被继承(构造方法是一个类独有的方法)
- 创建子类对象一定是先调用父类构造,再调用子类构造。(并且只有子类构造才能调用父类构造)。
- 子类构造可以通过super关键字调用父类有参构造 无参super() 有参super(参数列表) 。
- super父类构造调用,必须是子类构造中的第一行语句。(并且一个子类构造,只能调用一次super())。必须先有父再有子。
继承的特点: Java中类与类之前是单继承的。但是可以多及继承。一个父类可以有多个子类。
2.4Object类
Object是所有类的父类,任何类都默认继承Object
Object类中的getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写。
equals()方法 在比较字符串时 比较的是俩个字符串的值。但是实际上equals方法比较的是地址值。
为什么String就可以用equals()比较值呢?
因为String类中重写了equals()方法,所以可以比较值。
3.final关键字
String类是用final关键字修饰的,所以字符串不可变
三种用法:
- 修饰类
final修饰的类不能被继承,也就意味着这个类其中的方法不能被重写。 - 修饰方法
final关键字修饰的方法不能被覆盖重写。表示一个最终的方法。 - 修饰变量
final修饰成员变量—》常量 命名必须全大写 一般多个单词使用下划线连接 D_AGE,CAT_AGE, PI
基本数据类型:使用final修饰的基本数据类型值不能变,并且只能被赋值一次。
引用数据类型:使用final修饰的引用类型,引用的地址值不能改变,但是对象的属性值
可以改变。
- 对于成员变量来说,使用final 修饰照样是不可变的,但是因为成员变量有默认值,所以 必须手动赋值。
- 对final修饰的成员变量来说,可以直接赋值,也可以通过构造方法赋值,但是必须二选 一。
- 如果要通过构造方法赋值,并且类中有多个构造方法,必须保证每一个构造方法都要对 final修饰的成员变量赋值。
4.基本类型包装类
4.1 概念
基本数据类型使用非常方便,但是我们没有对应的方法去操作它们,可以通过一个类把基本数据类型包装起来,在类中定义一些方法,这个类就叫包装类。我们可以使用包 装类中定义的方法去操作基本数据。
基本数据类型和对应的包装类:
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
4.2自动装箱与自动拆箱
- 装箱
基本数据类型转换成包装类 - 拆箱
包装类转换成基本数据类型
4.3基本数据类型与字符串之间的转换
基本类型(数字)----》字符串(String)
- 可以使用数字直接+空字符串
例如: String a = 5 + “”; - 使用Integer包装类的方法 toString(int i);
例如: String a = Integer.toString(100); - 使用String类的方法valueOf(int i)
例如:String a = String.valueOf(100);
** 字符串----》基本数据类型(数字)**
只有数字类型的字符串,才可以转换成数字
使用包装类的方法xxx.parseXXX(“5”); NumberFormatException 数字格式异常
5.多态
多态就是接口的多种不同实现方式称为多态。允许子类类型赋值给父类类型。多态的前提是继承和方法重写。
多态是父类对象表现多种子类的形态的能力的特征。多态就是父类引用子类对象,向同一个父类的不同子类发送同一条消息,行为不同。
对于父类中的一个方法,在不同子类中有不同的实现。父类引用子类对象, 调用父类被重写的方法时,子类有不同的响应。这就是多态。
作用:
实现程序设计的开-闭原则,对扩展开放,对修改关闭。
5.1实现多态
- 继承:子类继承父类
- 重写:子类方法重写父类方法
- 向上转型:父类引用指向子类对象
- 调用父类被重写的方法时,不同的子类效果不同。
5.2向上转型、向下转型
向上转型:父类引用子类对象,自动成立,缺点是失去调用子类都有方法的能力
向下转型:子类引用父类对象,强制转换,需要使用instanceof进行类型判断。
5.3抽象类
抽象类:如果一个类只是一个概念,没有具体的形象,我们可以把这个类定义为抽象类
抽象类的关键字:abstract
抽象类的使用场景:一般作为顶层类(父类),被子类继承
抽象类
[权限修饰符] abstract class 类名{}
抽象方法:抽象方法没有方法体,也没有{}
[权限修饰符] abstract 返回值 方法名();//没有大括号
特点:
1.抽象类不能创建对象,不能new对象。抽象类的关键字是abstract。
2.抽象类可以定义抽象方法,也可以没有抽象方法
3.有抽象方法的类一定要定义成抽象类
4.抽象类中可以定义实例方法
5.抽象类可以定义构造方法,在子类中可以调用抽象类的构造方法 6.子类继承了抽象类,则一定要重写/实现其中的抽象方法,如果没有实现父类的抽象方法, 则子类也要变成抽象类
7.抽象方法需要在方法前写abstract关键字,并且不能有方法体(不能写大括号)
6.接口
接口:
- 一种标准、规范,大家都要遵从这个规范使用;
- 对行为(方法)的抽象(与抽象类对比,抽象类有特征和行为,而接口只关注行为);
- 一系列抽象方法的集合;
- 定制规则,展现多态;
- 接口和抽象类的地位等同,作为顶级存在(父类)
- 实现接口意味着拥有了接口所表示的能力
接口关键字:interface
实现接口:implements
6.1Java中的接口
接口定义的格式:
[权限修饰符] interface 接口名{};
接口的使用步骤:
1.接口中的方法不能直接使用,必须有一个实现类来实现接口
[权限修饰符] class 类名 implements 接口1,接口2,接口3。。。{} public class Mouse implements USB{}
2.接口的实现类必须(覆盖重写)实现 接口中所有的抽象方法
3.创建实现类的对象,进行方法的调用。
注意:如果实现类没有覆盖重写接口中的方法,那么这个实现类自己就必须是抽象类。
接口中可以包含的内容:
- 常量
// 接口中的常量使用public static final 三个关键字修饰。
// 定义常量的格式
public static final int AGE = 10;
// 使用接口中的常量
接口名.常量名
- 抽象方法(1.8新增)
接口中的抽象方法必须是两个固定的关键字修饰 public abstract。这两个关键字可以省 略不写。 - 默认方法
default 增强接口的通用能力。
default 返回值 方法名(){} //默认方法有方法体
- 静态方法(1.8新增)
提供通用实现,接口中的静态方法只能通过接口名调用,不能通过实现类调用
static 返回值 方法名(){} // 静态方法有方法体
6.2接口的特点
- 接口不能实例化,不能有构造方法
- 接口中的方法都是抽象方法,jdk8之后接口中可以定义默认方法和静态方法
- 接口中的成员变量默认都是public static final修饰的
- 实现类实现接口必须实现接口中的所有方法
- 多实现:一个类可以实现多个接口
- 接口可以继承接口:A extends B
6.3接口和抽象类的区别
应用场景:抽象类是对事物属性和行为的抽象,符合is…a关系; 接口是对行为的抽象,实现接口,拥有相应的功能;
相同点:都是顶级的父类存在的
抽象类和接口的对比
面试
6.4面向对象三大特征
总结
类与类之间是单继承的
类与接口是多实现的:一个类可以实现多个接口(这个要将所有实现的接口中的抽象 方法都实现),方便后期维护(修改,扩展)
接口与接口之间是多继承的:一个接口A如果继承了接口B和接口C,那么A接口可以同 时拥有B和C接口的所有功能,并且还可以拥有属于自己的方法。
接口没有构造方法。 接口多态:一个USB接口可以表现出鼠标形态,键盘的形态,U盘的形态。。。。。。