JavaSE----10.Java 面向对象
10.Java 面向对象
1、OOP(Object Oriented Programming): 面向对象程序设计
- 本质:以类的方式组织代码,以对象的组织(封装)数据。
- 面向对象编程核心思想:万物皆对象。
- OOP思想开发原则:高内聚,低耦合
- 耦合:类与类之间的关系
- 内聚:自身完成事情的能力
- 三大特性:封装、基础、多态
- 封装:封装就是将对象的属性和行为抽象出来包装到类中。
- 继承:继承就是将具有相同属性和行为的对象抽象出来并包装成一个父类让子类继承。
- 多态:多态就是多种形态,相同的属性和行为,却有不同的表现方式,父类的引用指向子类。
2、特性之一:封装
-
封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。
-
封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
-
实现封装:
- 修改属性的可见性来限制对属性的访问(一般限制为private)
- 对每个值属性提供对外的公共方法。
public class Person {
/**
* 修改属性的可见性来限制对属性的访问
* 将 name 和 age 属性设置为私有的,
* 只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
*/
private String name;
private int age;
//对每个值属性提供对外的公共方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
> 以上实例中public方法是外部类访问该类成员变量的入口。
> 通常情况下,这些方法被称为getter和setter方法。
>因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。
3、特性之二:继承
-
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法。
-
Java中的继承使用的是
extends
关键字,继承的类叫做子类(派生类或者超类),被继承的类叫做父类(或者基类)。类与类之间产生特殊 - 一般的关系,即is-a关系。 -
对于子类可以继承父类中的成员变量和成员方法,如果子类中出现了和父类同名的成员变量和成员方法时,父类的成员变量会被隐藏,父类的成员方法会被覆盖。需要使用父类的成员变量和方法时,就需要使用super关键字来进行引用。
-
在 Java 中类的继承是单一继承,但父类可以被多个子类继承。Java支持多层继承
-
子类只能继承父类的所有非私有的成员变量和方法。
-
继承的优点:
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
-
继承的缺点:
- 增加了耦合性
-
类的继承格式:
public class 子类类名 extends 父类类名{
}
案例:
//父类
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void speak(){
System.out.println(name+"正在说话!");
}
}
//子类继承父类
public class Teacher extends Person {
}
//测试类
public static void main(String args[]){
//实例化子类
Teacher t = new Teacher();
t.setName("繁星");
t.speak();
}
-
何时适合用继承
- 子类需要额外增加属性,而不仅仅是属性值的改变。
- 子类需要增加自己独有的行为方式。
-
重写:
-
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。
-
重写规则(重写遵循"两同两小一大"规则):
- 两同:方法名、形参列表相同
- 两小:
- 子类方法返回值类型应比父类方法返回值类型更小或相等
- 子类方法声明抛出的异常类应比父类方法抛出的异常类更小或相等
- 一大:子类方法的访问权限应比父类方法访问权限更大或相等
-
构造方法不能被重写。
-
只重写父类的方法。
-
声明为private的方法不能被重写。
-
声明为 final 的方法不能被重写。
-
声明为 static 的方法不能被重写,属于类,不属于实例。
-
Override 和 Overload 的区别?
- Override为重写,Overload为重载
- 方法重写:子类中出现和父类中方法声明一模一样的方法。返回值类型相同,方法名和参数列表一模一样。主要发生在子类和父类的同名方法之间。
- 方法重载:本类中出现方法名相同,参数列表不同的方法。主要发生同一类的多个同名方法之间。
- 方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
-
4、特性之三:多态
-
多态是同一个行为具有多个不同表现形式或形态的能力。
-
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
-
多态的转型
- 向上转型:多态本身就是向上转型过的过程
- 使用格式:父类类型 变量名 = new 子类类型();
- 适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
- 向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型
- 使用格式:子类类型 变量名=(子类类型) 父类类型的变量;
- 适用场景:当要使用子类特有功能时。
- 向上转型:多态本身就是向上转型过的过程
-
多态的定义与使用格式
- 定义格式:
父类类型 变量名 = new 子类类型();
- 定义格式:
-
案例:
//父类
public class People {
public void eat(){
System.out.println("吃饭");
}
}
//Teachers类继承父类
class Teachers extends People{
@Override
public void eat(){
System.out.println("吃樱桃");
}
public void teach(){
System.out.println("认真授课");
}
}
//Stu继承父类
class Stu extends People{
@Override
public void eat(){
System.out.println("吃水煮肉片");
}
public void study(){
System.out.println("好好学习");
}
}
//测试类
public class Test {
public static void main(String[] args) {
People people = new People();
people.eat();
System.out.println("--------------------");
People p1 = new Stu();
p1.eat();
System.out.println("--------------------");
People p2 = new Teachers();
p2.eat();
System.out.println("--------------------");
//调用特有的方法
Stu s=(Stu)p1;
s.study();
System.out.println("--------------------");
Teachers teachers = (Teachers) p2;
teachers.teach();
}
}
5、抽象类
- 用 abstract 关键字来修饰一个类时,这个类叫作抽象类。抽象类是它的所有子类的公共属性的集合,是包含一个或多个抽象方法的类。抽象类可以看作是对类的进一步抽象。
- 抽象类定义规则:
- 抽象类和抽象方法必须用 abstact 关键字来修饰
- 抽象类不能直接实例化
- 抽象方法只声明,而不需要方法体
- 含抽象方法的类必须被声明为抽象类
- 抽象类里面可以有一般的方法
- 子类在继承抽象类后,用的是"实现"而不是"重写"
- 在 Java 语言中使用 abstract class 来定义抽象类
6、接口
- Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
- 接口特性:
- 接口是隐式抽象的,当声明一个接口的时候,不必使用 abstract 关键字。
- 接口中方法也是隐式抽象的,声明时不需要 abstract 关键字。
- 接口中的方法都是公有的。
- Interface 关键字用来声明一个接口
- 接口的声明语法格式:
[修饰符] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
- 案例:
public interface Animal {
void eat();
void travel();
}
- 接口的实现:
- 类使用
implements
关键字实现接口。
- 类使用
- 案例:
public class MammalInt implements Animal{
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
@Override
public void eat(){
System.out.println("Mammal eats");
}
@Override
public void travel(){
System.out.println("Mammal travels");
}
}
- 接口与类的区别:
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
7、instanceof 关键字
- 作用:用来判断某个对象是否属于某种数据类型。
- 注意:返回类型为布尔类型
8、this 关键字
- this.属性名称:指的是访问类中的成员变量,用来区分成员变量和局部变量
- this.方法名称:用来访问本类的成员方法
- this():访问本类的构造方法
- this() 不能使用在普通方法中 只能写在构造方法中
- 必须是构造方法中的第一条语句
9、super 关键字
- super用于限定该对象调用它从父类继承得到的实例变量或方法。
- 注意点:
- super 调用父类的构造方法,必须在构造方法的第一个
- super 只能出现在子类的方法或构造方法中
- super 和 this 不能同时调用构造方法
10、static 关键字
-
在 Java 语言中,static 主要有4中使用情况:成员变量、成员方法、代码块和内部类
-
static成员变量:
- Java类提供了两种类型的变量:用 static 关键字修饰的静态变量和不用 static 关键字修饰的实例变量。静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了。对静态变量的引用有两种方式,分别是“类.静态变量"和”对象.静态变量"
- 实例变量属于对象,只有对象被创建后,实例变量才会被分配内存空间,才能被使用,它在内存中存在多个复制,只有用“对象.实例变量”的方式来引用。
-
static成员方法:
- Java 中提供了static方法和非 static 方法。static 方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以被使用。
- static 方法中不能使用 this 和 super 关键字,不能调用非 static 方法,只能访问所属类的静态成员变量和成员方法,因为当 static 方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。同理,static 方法也不能访问非 static 类型的变量。
- static 一个很重要的用途就是实现单例设计模式。
-
static 代码块
- static 代码块在类中是独立于成员变量和成员方法的代码块的。
- 注意:static 代码块只会被执行一次
-
静态类
- 通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。
-
static 与 final 结合使用表示的意思:
- 对于变量,若使用 static final 修饰,表示一旦赋值不能修改,并且通过类名可以访问。
- 对于方法,若使用 static final 修饰,表示该方法不可被覆盖,并且可以通过类名直接访问。
11、final 关键字
- 被final修饰的类不可以被继承
- 被final修饰的方法不可以被重写
- 被final修饰的变量不可以被改变
- final方法的好处:
- 提高了性能,JVM在常量池中会缓存final变量
- final变量在多线程中并发安全,无需额外的同步开销
- final方法是静态编译的,提高了调用速度
- final类创建的对象是只可读的,在多线程可以安全共享
12、implements 关键字
- 关键字 implements 是一个类实现一个接口用的关键字。它是用来实现接口中定义的抽象方法。实现一个接口,必须实现接口中的所有方法。使用 implements 关键字可以变相的使 java 具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
13、extends 关键字
- extends 表示对父类的继承,可以实现父类,也可以调用父类初始化。而且会重写父类定义的变量或者函数。在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
14、Java中访问控制符
控制符 | 权限 |
---|---|
private | 在当前类中可访问 |
default | 在当前包内和访问 |
protected | 在当前类和它派生的类中可访问 |
public | 公众的访问权限,谁都能访问 |