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。

相关文章
|
2天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
28 17
|
3天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
7天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
5天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
8 2
|
7天前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
17 3
|
Java 数据库 容器
|
8天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
79 38
|
5天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
9天前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
25 1
[Java]线程生命周期与线程通信
|
7天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。