Java基础教程(8)-Java中的面向对象和类(二)

简介: 【4月更文挑战第8天】面向对象的三大特征是封装、继承和多态。封装是将数据和操作数据的代码封装在类中,通过访问控制(如Java的public、private等)来保护数据。继承允许子类继承父类的特性,实现代码复用,分为实现继承和接口继承。多态则指同一方法在不同对象上表现出不同行为,实现动态绑定。重载(Overloading)是编译期多态,通过参数列表区分同名方法;重写(Overriding)是运行期多态,子类可覆盖父类方法。

面向对象的三大基本特征

  • 封装(Encapsulation)
  • 继承(Inheritance)
  • 多态(Polymorphism)

封装

所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

封装是面向对象的特征之一,是对象和类概念的主要特性。简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。

访问控制

封装提供了一个重要属性:访问控制(access control)。通过封装你可以控制程序的哪一部分可以访问类的成员。通过控制访问,可以阻止对象的滥用;

一个成员如何被访问取决于修改它的声明的访问指示符。Java提供一套丰富的访问指示符; Java的访问指示符有public(公共的,全局的)、private(私有的,局部的)、和protected(受保护的)。Java也定义了一个默认访问级别default;

  • 当一个类成员被public指示符修饰时,该成员可以被你的程序中的任何其他代码访问。
  • 当一个类成员被指定为private时,该成员只能被它的类中的其他成员访问。
  • 如果不使用访问指示符,该类成员的默认访问设置为在它自己的包内为public,但是在它的包以外不能被存取;

对于成员变量和方法的作用域,public,protected,private 以及不写之间的区别:

  • public : 表明该成员变量或者方法是对所有类或者对象都是可见的,所有类或者对象都可以直接访问。

  • private : 表明该成员变量或者方法是私有的,只有当前类对其具有访问权限,除此之外其他类或者对象都没有访问权限.子类也没有访问权限。

  • protected : 表明成员变量或者方法对类自身,与同在一个包中的其他类可见,其他包下的类不可访问,除非是他的子类。

  • default : 表明该成员变量或者方法只有自己和其位于同一个包的内可见,其他包内的类不能访问,即便是它的子类

继承

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。

继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。

实现继承和接口继承的区别:

实现继承:

如果多个类的某个部分的功能相同,那么可以抽象出一个类出来,把他们的相同部分都放到父类里,让他们都继承这个类。
使用 extends 关键字实现

接口继承(实现)

如果多个类处理的目标是一样的,但是处理的方法方式不同,那么就定义一个接口,也就是一个标准,让他们的实现这个接口,各自实现自己具体的处理方法来处理那个目标。
通过 implements 关键字

  • 继承的根本原因是因为要复用,而实现的根本原因是需要定义一个标准。
  • Java 中支持一个类同时实现多个接口,但是不支持同时继承多个类。

继承和组合
Java 代码的复用可以使用继承,组合等表现形式;(还有一种是代理)

  • 继承(Inheritance)是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;继承是一种 is-a 关系; 在写代码的时候就要指名具体继承哪个类,所以,在编译期就确定了关系。

  • 组合(Composition)体现的是整体与部分、拥有的关系,即 has-a 的关系; ,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在运行期确定;

public class ParentSon extends Parent{

    public Box box;

    @Override
    public void printName() {
        System.out.println("son");
    }


}

以上代码:
ParentSon继承于Parent类,是is-a关系
Parentson包含有Box 是has-a关系

建议在同样可行的情况下,优先使用组合而不是继承。因为组合更安全,更简单,更灵活,更高效。

只有当子类真正是超类的子类型时,才适合用继承

多态

所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用;

最常见的多态就是将子类传入父类参数中,运行时调用父类方法时通过传入的子类决定具体的内部结构或行为。

最具代表的是子类重写父类的方法和方法的重载;

方法的重写和重载

  • 重载(Overloading)
    简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法

  • 重写(Overriding)
    重写指的是在 Java 的子类与父类中有两个名称、参数列表都相同的方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类中原有的方法。

有人总结的重写和重载的不同很到位:

1、重载是一个编译期概念、重写是一个运行期间概念。
2、重载遵循所谓“编译期绑定”,即在编译时根据参数变量的类型判断应该调用哪个方法。
3、重写遵循所谓“运行期绑定”,即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法。
4、因为在编译期已经确定调用哪个方法,所以重载并不是多态。而重写是多态。重载只是一种语言特性,是一种语法规则,与多态无关,与面向对象也无关。(注:严格来说,重载是编译时多态,即静态多态。但是,Java 中提到的多态,在不特别说明的情况下都指
动态多态)

重载的例子:

  public int getWidth(){
   
        return 10;
    }

    public int getWidth(int a){
   
        return 11;
    }
    public int getWidth(int a,int b){
   
        return 12;
    }

重载的条件

被重载的方法必须改变参数列表;
被重载的方法可以改变返回类型;
被重载的方法可以改变访问修饰符;
被重载的方法可以声明新的或更广的检查异常;
方法能够在同一个类中或者在一个子类中被重载。

除了重载正常的方法外,构造函数也能够重载

重写的例子:

public class Parent {
    public void printName(){
        System.out.println("parent");
    }
}
public class ParentSon extends Parent{
    @Override
    public void printName() {
        System.out.println("son");
    }
}

重写的条件

参数列表必须完全与被重写方法的相同;
返回类型必须完全与被重写方法的返回类型相同;
访问级别的限制性一定不能比被重写方法的强;
访问级别的限制性可以比被重写方法的弱;
重写方法一定不能抛出新的检查异常或比被重写的方法声明的检查异常更广泛的检查异常。
重写的方法能够抛出更少或更有限的异常(也就是说,被重写的方法声明了异常,但重写的方法可以什么也不声明)。
不能重写被标示为 final 的方法。
如果不能继承一个方法,则不能重写这个方法;

注意
声明成final的方法不能被重载。
声明一个final类,它的所有方法也都是final。

相关文章
|
14天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
37 17
|
6天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
49 4
|
10天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
26 2
|
14天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
14天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
14天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
3月前
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
58 7
|
22天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
16 3
|
22天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
28 2