【Java基础04】 Java隐藏和封装、类的继承、多态

1 隐藏和封装

1.1 封装 Encapsulation

封装指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

封装实现的目的如下:

(1)隐藏类的实现细节。

(2)让使用者只能通过实现预定的方法来访问数据,限制成员变量的不合理访问。

(3)能进行数据检查,有利于保证对象信息的完整性。

(4)便于修改,提高代码的可维护性。

良好的封装应该从两方面考虑:

(1)将对象的成员变量和实现细节隐藏起来,不允许外部直接访问。

(2)把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作。

封装需要借助Java提供的访问控制符来实现。

一个类通常就是一个小的模块,我们应该让模块仅仅公开必须要让外界知道的内容,而隐藏其它一切内容。在进行程序设计时,要尽量避免一个模块直接修改或操作另一个模块的数据。模块设计追求强内聚(许多功能尽量在类的内部独立完成,不让外面干预)和弱耦合(提供给外部尽量少的方法调用)。

2 类的继承

2.1 Java中的继承

单继承特点(每个子类只有一个直接父类)、用extends(拓展)关键字实现。实现继承的类称为子类(小),被继承的类称为父类(大)。例如水果和苹果的关系,苹果继承了水果,苹果是水果的子类,苹果是一种特殊的水果。父类包含的范围总比子类包含的范围大。

2.2 重写父类的方法

一般地,子类以父类为基础,额外再增加新的成员变量和方法。有一种情况是:当来自父类的某一种方法不能适应子类的需要时,子类需要重写(Override)继承自父类的方法。也成为方法覆盖(子类覆盖了父类的方法)。

方法的重写要遵循“两同两小一大”规则,“两同”即方法名相同、形参列表相同;“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;“一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等。尤其需要指出的是,覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法。

当子类覆盖了父类方法后,子类对象将无法访问父类中被覆盖的方法,但可以在子类方法中调用父类中被覆盖的方法(被覆盖的是实例方法用super,是类方法用父类类名)。

重写和重载:重载发生在同一个类的多个同名方法之间,重写发生在子类和父类的同名方法之间。

2.3 super限定

如果需要在子类方法中调用父类被覆盖的实例方法,则可以使用super限定来调用父类被覆盖的实例方法。

2.4 调用父类构造器

子类不会获得父类的构造器,但子类构造器里可以调用父类构造器的初始化代码,类似于一个构造器调用另一个重载的构造器。

用super。

 super调用父类构造器,this调用重载构造器。

创建任何对象总是从该类所在继承树最顶层类的构造器开始执行,依次向下执行,最后执行本类的构造器。如果某个父类通过this调用了同类中重载的构造器,就会依次执行父类的多个构造器。

3 多态 Polymorphism

3.1多态性

1.Java引用变量有两个类型: 一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。

2.Java允许把一个子类对象直接赋给一个父类引用变量,无需任何类型转换,因此当把一个子类对象(如Son)直接赋给父类引用变量(如Father)时,语句Father son1=new Son(); ,son1的引用变量编译时类型是Father,运行时类型是Son,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征。这样就有可能出现相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态。

3.如果此时运行一段来自Son类中的Father所没有的方法,比如son1.test();,在Father中没有提供这个方法,因此会编译错误(编译时类型为Father)。(虚方法调用 仅有子类重写父类的方法

4.引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法。因此,编写Java代码时,引用变量只能调用声明该变量时所用类里包含的方法。例如,通过Object p= new Person(代码定义一个变量p,则这个p只能调用Object类的方法,而不能调用Person类里定义的方法。

5.通过引用变量来访问其包含的实例变量时,系统总是试图访问它编译时类型所定义的成员变量,而不是它运行时类型所定义的成员变量。但可以通过引用变量的强转来改变。

3.2 引用变量的强制类型转换

编写Java程序时,引用变量只能调用它编译时类型的方法,而不能调用它运行时类型的方法,即使它实际所引用的对象确实包含该方法。如果需要让这个引用变量调用它运行时类型的方法,则必须把它强制类型转换成运行时类型,强制类型转换需要借助于类型转换运算符。
类型转换运算符是小括号,类型转换运算符的用法是: (ype)variable, 这种用法可以将variable 变量转换成-一个type类型的变量。前面在介绍基本类型的强制类型转换时,已经看到了使用这种类型转换运算符的用法,类型转换运算符可以将- -个 基本类型变量转换成另-个类型。
除此之外,这个类型转换运算符还可以将一-个引用类型变量转 换成其子类类型。这种强制类型转换不是万能的,当进行强制类型转换时需要注意:

1.基本类型之间的转换只能在数值类型之间进行,这里所说的数值类型包括整数型、字符型和浮点型。但数值类型和布尔类型之间不能进行类型转换。
2.引用类型之间的转换只能在具有继承关系的两个类型之间进行,如果是两个没有任何继承关系的类型,则无法进行类型转换,否则编译时就会出现错误。如果试图把一个父类实例转换成子类类型,则这个对象必须实际上是子类实例才行(即编译时类型为父类类型,而运行时类型是子类类型),否则将在运行时引发ClassCastException异常。

3.3 instanceof运算符

当把子类对象赋给父类引用变量时,被称为向上转型(upcasting),这种转型总是可以成功的,这也从另一个侧面证实了子类是一种特殊的父类。这种转型只是表明这个引用变量的编译时类型是父类,但实际执行它的方法时,依然表现出子类对象的行为方式。但把一个父类对象赋给子类引用变量时,就需要进行强制类型转换,而且还可能在运行时产生ClassCastException异常,使用instanceof 运算符可以让强制类型转换更安全。

instanceof运算符的前-个操作数通常是-一个引用类型变量,后一个操作数通常是-一个类(也可以是接口,可以把接口理解成一种特殊的类), 它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是,则返回true,否则返回false。
在使用instanceof 运算符时需要注意: instanceof 运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系,否则会引起编译错误。

原文地址:https://www.cnblogs.com/discoverspace/p/12247369.html

时间: 2024-08-08 21:11:59

【Java基础04】 Java隐藏和封装、类的继承、多态的相关文章

Java基础04 封装与接口(转载)

数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对象的数据成员和方法. 我们将要封装(encapsulation)对象的成员(成员包括数据成员和方法),从而只允许从外部调用部分的成员.利用封装,我们可以提高对象的易用性和安全性. 封装与接口 封装(encapsulation)是计算机常见的术语,即保留有限的外部接口(interface),隐藏具体实

Java基础12:深入理解Class类和Object类

Java基础12:深入理解Class类和Object类 Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI. 这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类.Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建. 说白了就是: Class类也是类的一种,只是名字和class关键字高度相似.Java是大小写敏感的语言.

Java基础复习笔记系列 五 常用类

Java基础复习笔记系列之 常用类 1.String类介绍. 首先看类所属的包:java.lang.String类. 再看它的构造方法: 2. String s1 = “hello”: String s2 = “hello”:结论:s1 == s2. 字符串常量放在data区. 3. String s3 = new String("hello"); String s4 = new String("hello");结论:s3 != s4.但s3.equals(s4).

【java基础】Java反射机制

一.预先需要掌握的知识(java虚拟机)  1)java虚拟机的方法区:  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 这个类型的全限定名 这个类型的直接超类的全限定名 这个类型是类类型还是接口类型

【Java基础】Java面试题目整理与解说(二)

1.Collection 和 Collections 的差别. Collection 是集合类的上级接口,继承于他的接口主要有 Set 和 List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.HashMap 和 Hashtable 的差别. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完毕了 Map 接口,HashMap是非线程安全,效率上可能高于 Hashtable.在多个线程

Java基础 之Java动态绑定详解

程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定 静态绑定(早绑定 编译器绑定): 在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现.例如:C. 针对java简单的可以理解为程序编译期的绑定:这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定 动态绑定(迟绑定 运行期绑定): 后期绑定:在运行时根据具体对象的类型进行绑定. 若一种语言实现

【Java基础】Java面试题目整理与讲解(二)

1.Collection 和 Collections 的区别. Collection 是集合类的上级接口,继承于他的接口主要有 Set 和 List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.HashMap 和 Hashtable 的区别. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,HashMap是非线程安全,效率上可能高于 Hashtable.在多个线程

JAVA基础——面向对象三大特性:封装、继承、多态

JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据.     隐藏类的实例细节,方便修改和实现. 3.封装的实现步骤 需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作.当然最好使用get/set方法,比较标准. A.访问修饰符 从表格可以看出从上到下封装性越来越差. B.this关键字 1.this关键字代表当前

【Java基础08】内部类、枚举类、日期和时间、Math、Random

1 内部类 1.1 概念 大部分时候,类被定义成一个独立的程序单元,在某些情况下,也会把一个类放到另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,包含内部类的类被称为外部类. 1.2 作用 1.提供更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类. 2.内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问.但外部类不能访问内部类的实现细节,例如内部类的成员变量. 3.匿名内部类适合用于创建那些仅需要一次使用的类