Java 面向对象 -- 基础认知

举报
测试-开发阿泽 发表于 2022/12/26 21:47:54 2022/12/26
【摘要】 Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程

面向对象基础认知

类和对象

对象:是真实存在的具体实例

类(设计图):是对象共同特征的描述

在 JAVA中,必须先设计类,才能获得对象

如何定义类:

public class 类名{成员变量 成员方法 构造器 代码块 内部类 }

如何得到类的对象:

​ 类名 对象名 =new 类名();

如何使用对象:

​ 访问属性:对象名.成员变量

​ 访问行为:对象名.方法名(…)

定义类的补充注意事项:

  1. 成员变量的完整定义格式是:修饰符 数据类型 变量名 称 = 初始化值; 一般无需指定初始化值,存在默认值。
  2. 类名首字母建议大写,且有意义,满足“驼峰模式”。
  3. 一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。 实际开发中建议还是一个文件定义一个class类。

this关键字

this关键字可以出现在成员方法,构造器中,代表当前对象的地址

作用:访问当前对象的成员变量,成员方法

面向对象的三大特征:封装,继承,多态

封装

定义:合理隐藏,合理暴露, 隐藏实现细节,暴露出合适的访问方式

封装的实现步骤:

  1. 一般对成员变量使用private(私有)关键字修饰进行隐藏,private修饰后该成员变量就只能在当前类中访问。
  2. 提供public修饰的公开的getter、setter方法暴露其取值和赋值。

作用:

  1. 加强了程序代码的安全性
  2. 提升开发效率,同时可以让程序更容易理解与维护

成员变量及局部变量的区别

区别 成员变量 局部变量
类中位置不同 类中,方法外 常用于方法中
初始化值不同 有默认初始化值 没有,使用之前需要完成赋值
内存位置不同 堆内存 栈内存
生命周期不同 随着对象的创建而存在,随着对象的消 失而消失 随着方法的调用而存在,随着方法的运行结束 而消失
作用域 在所归属的大括号中

static

作用:

  1. static是静态的意思,可以修饰成员变量和成员方法。
  2. static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

分类:

静态成员方法(有static修饰,属于类,内存中加载一次):常表示如在线人数信息、等需要被共享的信息,可以被共享访问

访问格式:类名.静态成员方法(推荐) 对象.静态成员方法

实例成员方法(无static修饰,存在于每个对象中):常表示姓名name、年龄age、等属于每个对象的信息

访问格式:对象.实例成员方法

static访问注意实现:

  1. 静态方法只能访问静态的成员,不可以直接访问实例成员。
  2. 实例方法可以访问静态的成员,也可以访问实例成员。
  3. 静态方法中是不可以出现this关键字的。

继承

Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系。子类可以叫派生类,父类可以叫基类或超类,Java中子类更强大。

好处:

提高代码复用性,减少代码冗余,增强类的功能扩展性

继承设计规范:

子类们相同特征(共性属性,共性方法)放在父类中定义,子类独有的的属性和行为应该定义在子类自己里面

继承特点:

①子类可以继承父类的属性和行为,但是子类不能继承父类的构造器。

②Java是单继承模式:一个类只能继承一个直接父类。

③Java不支持多继承、但是支持多层继承。

④Java中所有的类都是Object类的子类。

Object特点:

Java中所有类,要么直接继承了Object , 要么默认继承了Object , 要么间接继承了Object, Object是祖宗类

在子类方法中访问成员(成员变量、成员方法)满足:就近原则

  1. 先子类局部范围找
  2. 然后子类成员范围找
  3. 然后父类成员范围找,如果父类范围还没有找到则报错。

如果子父类中,出现了重名的成员,会优先使用子类的,此时如果一定要在子类中使用父类的怎么办?

可以通过super关键字,指定访问父类的成员。super.父类成员变量/父类成员方法

方法重写

在继承体系中,子类出现了和父类中一模一样的方法声明

方法重写的应用场景

  1. 当子类需要父类的功能,但父类的该功能不完全满足自己的需求时。
  2. 子类可以重写父类中的方法。

方法重写注意事项和要求

  1. 重写方法的名称、形参列表必须与被重写方法的名称和参数列表一致。
  2. 私有方法不能被重写。
  3. 子类重写父类方法时,访问权限必须大于或者等于父类 (暂时了解 :缺省 < protected < public)
  4. 子类不能重写父类的静态方法,如果重写会报错的。

子类继承父类后构造器的特点:

子类中所有的构造器默认都会先访问父类中无参的构造器,再执行自己。

super调用父类有参数构造器的作用:

通过调用父类有参数构造器来初始化继承自父类的数据

this和super详情

this:代表本类对象的引用;

super:代表父类存储空间的标识

关键字 访问成员变量 访问成员方法 访问构造方法
this this.成员变量 访问本类成员变量 this.成员方法(…) 访问本类成员方法 this(…) 访问本类构器
super super.成员变量 访问父类成员变量 super.成员方法(…) 访问父类成员方法 super(…) 访问父类构造器

实际上,在以上的总结中,唯独只有this调用本类其他构造器我们是没有接触过的。

final

作用:

  1. final 关键字是最终的意思,可以修饰(方法,变量,类)
  2. 修饰方法:表明该方法是最终方法,不能被重写。
  3. 修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)。
  4. 修饰类:表明该类是最终类,不能被继承。

final修饰变量的注意

  1. final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
  2. final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。

接口

接口也是一种规范

public interface 接口名{
    //常量
}

用法:

接口是用来被类实现(implements)的,实现接口的类称为实现类。实现类可以理解成所谓的子类。

修饰符 class 实现类 implements 接口1, 接口2, 接口3 , ... {
}
实现的关键字:implements

从上面可以看出,接口可以被类单实现,也可以被类多实现。

实现的关键字:implements

接口实现的注意事项:

一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。

基本小结:

类和类的关系: 单继承

类和接口的关系: 多实现

接口和接口的关系: 多继承,一个接口可以同时继承多个接口

接口多继承的作用

规范合并,整合多个接口为同一个接口,便于子类实现

接口的注意事项:

  1. 接口不能创建对象
  2. 一个类实现多个接口,多个接口中有同样的静态方法不冲突
  3. 一个类继承了父亲,同时又实现了接口,父类中和接口中有同名方法,默认同父类的
  4. 一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写方法即可
  5. 一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承

多态

同类型的对象,执行同一个行为,会表现出不同的行为特征

父类类型 对象名称 = new 子类构造器;
接口     对象名称 = new 实现类构造器;

多态中成员访问特点

方法调用:编译看左边,运行看右边。

变量调用:编译看左边,运行也看左边。(多态侧重行为多态)

多态的前提

有继承/实现关系;有父类引用指向子类对象;有方法重写

优势:

在多态形式下,右边对象可以实现解耦合,便于扩展和维护。

Animal a = new Dog();
a.run(); // 后续业务行为随对象而变,后续代码无需修改

定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利

多态下引用数据类型的类型转换

自动类型转换(从子到父):子类对象赋值给父类类型的变量指向。

强制类型转换吗(从父到子)

此时必须进行强制类型转换:子类 对象变量 = (子类)父类类型的变量

构造方法:

是一个特殊的方法,用来初始化的一个新的对象,咋创建对象之后自动调用

特点

方法名必须与类名相同

可以有0个或1个或多个参数

没有任何的返回值,包括void

默认的返回类型就是对象类型本身

只能与new运算符结合使用

注意

如果构造方法定义了返回值类型或使用void声明构造方法没有返回值,编译不会出错,但是Java会把这个构造方法当成普通的方法进行处理

构造方法不能被static,final,synchronized ,abstract,native修饰,

因为构造方法是由于初始化一个新的对象,所以用static修饰是没有意义的

因为构造方法不能被子类继承,所以用final,abstract修饰是没有意义的

因为多线程不会同时创建内存地址相同的同一个对象,所以用synchronized 修饰是没有必要的

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。