Java面向对象三大特性

本文详细介绍了面向对象的三大特性:封装、继承和多态。封装强调数据隐藏和提供公共接口,减少耦合度;继承允许类的层级结构,提高代码复用,多态则增强了类的灵活性,通过父类引用调用子类方法实现不同行为。文章还深入探讨了各种特性在Java中的实现和应用场景,包括权限修饰符、子类继承、多态性转换等关键概念。
摘要由CSDN通过智能技术生成

一、面向对象特性之封装性

1. 为什么要封装?

Java程序设计追求“高内聚,低耦合”

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉

  • 低耦合:仅对外暴露少量的方法用于使用

隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露岀来。这就是封装性的设计思想。

2. 应用情景

  • 当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。
  • 这里,赋值操作要受到属性的数据类型和存储范围的制约。除此之外,没其他制约条件。
  • 但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件。
  • 这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。
  • 比如:setName()同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private)。此时,针对于属性就体现了封装性

3. 封装具体体现

体现一:
将类的属性xxx私化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值

体现二:不对外暴露的私有的方法

体现三:单例模式(将构造器私有化)

体现四:如果不希望类在包外被调用,可以将类设置为缺省的。

4. Java中的四种权限修饰符

  • 通过对不同的方法属性设置不同的权限修饰符来达到对类进行封装的目的。

  • 权限从小到大顺序为:private < 缺省 < protected < public

  • 具体的修饰范围:

修饰符类内部同一个包不同包的子类同一个工程
pubicTTTT
protectTTT
缺省TT
privateT

权限修饰符说明:

  • 修饰类:只能使用:缺省、public
  • 类的内部结构:属性、方法、构造器、内部类
  • 局部变量前不能放置任何访问修饰符 (private,public,和protected)。

二、面向对象特性之继承性

1. 继承性概述

  • 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。
  • 对象的一个新类可以从现有的类中派生,这个过程称为类继承。
  • 新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。
  • 派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
  • Java中只允许单继承,但允许多层继承。

继承性格式:

class A extends B{}
     A:子类、派生类、subclass
     B:父类、超类、基类、superclass

2. 引入继承性的好处

  • 减少了代码的冗余,提高了代码的复用性
  • 便于功能的扩展
  • 为之后多态性的使用,提供了前提

3.子类继承父类后的区别

  • 子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私的结构。只因为封装性的影响,使得子类不能直接调用父类的结构而已。
  • 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。子类和父类的关系,不同于子集和集合的关系。

关于继承的说明

  1. 一个类可以被多个子类继承。
  2. Java中类的单继承性:一个类只能有一个父类
  3. 多层继承:相当于父有子,子又有孙;
  4. 子父类是相对的概念。
  5. 子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
  6. 子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法
  7. 如果定义一个类时,没有使用extends去继承一个类,则它的父类是:java.lang.Object。
  8. 我们到底在什么时候使用继承呢?继承中类之间体现的是:”is a”的关系。
    如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

4.子类对象实例化的全过程

  • 子类继承父类以后,就获取了父类中声明的属性或方法。 创建子类的对象,在堆空间中,就会加载所父类中声明的属性。
  • 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,…直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所的父类的结构,所以才可以看到内存中父类中的结构,子类对象才可以考虑进行调用。
    在这里插入图片描述
    注:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。

一个类的初始化过程
静态变量、静态代码块
成员变量的初始化
->成员变量的默认初始化
->成员变量的显示初始化
构造代码块
构造方法初始化

子父类的初始化(分层初始化)
在这里插入图片描述

5.instanceof 运算符

概述:

  • 是二元运算符,左边是对象,右边是类;当对象是右面类或子类所创建对象时,返回true;否则,返回false。
public class Test{
	public static void main(String[] args) {
		Student s = new Student();
		System.out.println(s instanceof Person);
		System.out.println(s instanceof Student);
       }
}//两条语句的输出结果都是true

6.super关键字

1.super的用法和this很像

  • this代表本类对应的引用。
  • super代表父类存储空间的标识(可以理解为父类引用)

2.用法(this和super均可如下使用)

  • this.成员变量 super.成员变量
  • this ([参数1,参数2…]) super([参数1,参数2…])
  • this.成员方法([参数1,参数2…])
  • super.成员方法([参数1,参数2…])

7.继承中成员变量的关系

在子类方法中访问一个变量h

  • 查找当前类中有没有变量h
  • 依次上溯每个父类,查看每个父类(父类成员范围找)中是否有h直到Object
  • 如果没找到,则出现编译错误。
  • 上面步骤,只要找到h变量,则这个过程终止。

8.继承中构造方法的关系

为什么子类中所有的构造方法默认都会访问父类中空参数的构造方法?

  • 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。
  • 每一个构造方法的第一条语句默认都是:super()
  • 所以,构造方法的执行流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。

9.继承中成员方法的关系—重写父类方法

方法重写概述:

  • 子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。

注:

  • 子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。

  • 子类重写父类方法时,不能使用比父类中被重写的方法更严格的访问权限。

    “==”:方法名、形参列表相同。
    “≤”:返回值类型和声明异常类型,子类小于等于父类。
    “≥”:访问权限,子类大于等于父类。

三、面向对象特性之多态性

1.概述

定义:
在Java中,多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。

说明:
通常来说,在一个类中定义的属性和方法被其他类继承或重写后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现出的多种不同形态。

作用:通过多态,消除了类之间的耦合关系,大大提高了程序的可扩展性可维护性

注:

  • Java的多态性是由类的继承、方法重写以及父类引用指向子类对象体现的
  • 多态是方法的多态,不是属性的多态(多态与属性无关)
  • 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象
  • 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了

2.对象类型的转型

向上转型:

在多态的学习中,涉及到将子类对象当做父类类型使用的情况,此种情况在Java的语言环境中称为“向上转型”。即父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换。

Animal an1 = new Cat();     // 将Cat类对象当做Animal类型来使用
Animal an2 = new Dog();    // 将Dog类对象当做Animal类型来使用

注意:将子类对象当做父类使用时不需要任何显式地声明,需要注意的是,此时不能通过父类变量去调用子类特有的方法。

向下转型

向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时,我们就需要进行类型的强制转换,我们称之为向下转型!

public class TestCasting {
public static void main(String[] args) {
Object obj = new String("软件学院"); // 向上可以自动转型 
// obj.charAt(0) 无法调用。编译器认为obj是Object类型而不是String类型 /*
// 编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。 * 不然通不过编译器的检查。 */ 
String str = (String)obj; 
// 向下转型 
System.out.println(str.charAt(0)); // 位于0索引位置的字符
System.out.println(obj == str); // true.他们俩运行时是同一个对象 
}}

注意:

① 使用强转时,可能出现ClassCastException的异常。
② 为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
③ 只有对象A是B的子类实例化对象或者在下层的子类,才能向下转型
在这里插入图片描述

3.多态中的成员访问特点

A:成员变量

  • 编译看左边,运行看左边

B:构造方法

  • 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。

C:成员方法

  • 编译看左边,运行看右边

D:静态方法

  • 编译看左边,运行看左边(静态和类相关,算不上重写,所以,访问还是左边的)

为什么?
----由于成员方法存在方法重写,所以它运行看右边。

4.多态的利弊

多态的好处:

  • A:提高代码的维护性(继承体现)
  • B:提高代码的扩展性(多态体现)

多态的弊端:

  • 父不能使用子的特有功能。

现象:

  • 子可以当作父使用,父不能当作子使用。

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值