JAVA(基础) 面向对象二 三大特征

本文详细介绍了JAVA面向对象的三大特征:封装、继承和多态。封装强调隐藏内部细节,提供公共访问方式,如JavaBean的属性私有化和公共访问器。继承允许代码复用,子类可以重写父类方法,如`super`关键字的使用。多态则表现为父类引用指向子类对象,通过重写方法实现不同形态的表现。同时,文章还讨论了访问权限修饰符、`equals`和`toString`的重写以及类型转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JAVA面向对象二 三大特征

面向对象的特征是封装,继承和多态。这也是面向对象的重点和难点。在了解三大特征前,我们先了解下JavaBean。

JavaBean

JavaBean 泛指一些列的模板类,是一系列的统称

模板类|javabean|实体类|pojo…

属性私有化,公共的访问方式

私有的内容->配合公共访问方式一起使用

private 私有的 ,权限修饰符
被private修饰的成员只能在当前类中使用

公共访问方式
设置器 setter
访问器 getter

​ 设置器和访问器其实就是公共的成员方法

Package和import

Package

包:和我们平时用的文件夹一样。管理众多的java资源;提供多重命名空间。

我们平时用idea时,写代码的首行都是会自动生成一个包的。

定义规范:全部小写,每个层级之间用 . 分隔;一般都是公司域名倒着写.功能名|模块名

import

之前想我们用的Scanner (键盘录入),这都是需要导包的,因此import就是导包的关键字。当我们想要在A类中使用B类,就哟啊使用import。(创建B类的对象,调用B类的静态内容)

注意的是 同包下的类 和 java.lang 下的内容是不需要导包的。

语法: import 包名.类名;

​ 当一个包下需要多个类时,可以用 *****模糊匹配。import java.util.*;

​ 静态导入 用 import static 只导入一个类中的某个静态的内容。

JavaBean开发规范

alt+insert->generate

1.类是公共的

2.至少提供一个空构造,可选择的提供带参构造

3.属性私有化

4.提供公共的访问方式 setter getter

5.至少提供一个空构造器

5.重写toString

6.重写equals

arl+insert 可以自动生成 构造器,setter and getter ,toString,equals

封装

封装是隐藏内部的实现细节,对外提供公共的访问方式。

方法 和(属性私有化,公共的访问方式) 都是封装的体现。

好处:可以提高代码的复用性,提高程序的安全性

因此我们自定义模板类,属性都应该私有化,并提供公共的访问方式

属性私有化:用private(私有的) 修饰属性

公共的访问方式:使用设置器setter 和 访问器getter

public class Person {
    private String name;//私有成员属性
    public Person(){} //空构造器
    public Person(String name){ //带参构造器
        this.name = name;
    }

    //设置器:  为了私有的属性name赋值
    public void setName(String name){
        this.name = name;
    }
    //访问器: 为了获取私有属性name的值
    public String getName(){
        return name;
    }

继承

继承可以提高代码的复用性,子类一旦继承父类就有权使用父类中的内容,并且子类还可以扩展,即拥有自己独有的内容

java中的继承是单继承机制,即一个子类只能继承一个父类,但可以多实现(在接口中讲)。

单继承更加简单,但是不便于后期的维护,因此有了多实现来弥补其缺点,多实现会在之后的接口部分重点讲下。

//父类
class Person{
    public String name;
    public int age;

    public void sleep(){
        System.out.println("休息...");
    }
}

//子类
//学生类
class Student extends Person{
    public int id;  //学生编号

    //学习
    public void study(){
        System.out.println("正在学习...");
    }

}

重写

方法的重写是方法体的重新实现。我们在继承父类的方法的时候,有些方法是不适用于子类的,因此子类可以对方法进行重写。

要求:是不同的类;有继承或者实现的关系;方法签名相同(方法名+参数列表)

注意与重载的异同:它们都是方法的特性

​ 重载:同一个类的多个方法;方法名相同;参数列表不同(方法签名不同)

注意:
子类对象调用成员的时候,如果子类中有,就就近原则找子类的,子类没有找父类的
当子类中存在方法的重写,子类对象会调用子类中重写的方法,子类没有找父类

不能重写的方法:
1.被private修饰的方法 不能被重写
2.被 final 修饰的方法不能被重写
3.被 static 修饰的方法 不能被重写
并且如果子类中出现于父类静态方法同名的方法,要求也是静态的

检查重写的方式:
1.在行号的位置显示o箭头指向被重写的方法
2.在重写方法的上面添加一个@Override 强制检查此方法是否为一个重写方法,不是报错

重写的三个条件: 一般都是用相等的
1.== 子类重写方法与父类中的被重写方法 方法签名要求完全相等
2.<= 如果子类重写方法与父类中的被重写方法 返回值类型是基本数据类型,要求完全相等引用数据类型,子类<=父类。 子类的方法是重写父类的方法,当时引用数据类型的时候,如果返回值都比父类的大,就相当于父类有个鸡蛋,然后你继承了一个金蛋,根本就继承不到。

3.>= 子类重写方法的权限修饰符>=父类中被重写方法的权限修饰符
就像是下面说到的多态,如果子类的权限都比父类小,在多态中父类都没有权限调用子类的重写方法,这显然是不行的。

//父类的方法

class Person{
    public void sleep(){
        System.out.println("人正在休息...");
    }
}
//子类方法的重写
class Student extends Person{
    @Override
	public void sleep(){
        System.out.println("学生正在休息...");
    }
}

注意:@Override 放到重写的方法上面可以检查该方法是不是重写,如果不是就会报错。

访问权限修饰符

访问权限修饰符 : 修饰成员被访问的权限,不能修饰局部–>成员修饰符

修饰符本类中同包的类中不同包下的子类不同包的其他类
private私有的
default 默认的
protected 受保护的
public 公共的

default 修饰符在用的时候是省略不写的。一般的 class A 就是省略了default

super

super和this 比较像,因此要了解它们的区别

this关键字
1>用来指代当前对象(new)
构造器首行调用奔雷中的其他构造器 this(参数)
2> 区分同名变量问题 局部与成员

super
1> 指代父类对象

​ 在子类构造器的首行通过super(参数)调用父类的构造器
​ 2> 区分同名问题
​ 如果子类与父类存在同名情况(成员),在子类中默认就近原则找子类的,如果想要找父类中的同名成员,使用super.调用

​ 注意:如果子类中存在局部与成员同名情况,默认找局部,想要指代成员通过this.调用
​ 如果没有同名问题,this.和super.都可以省略

​ 如果子类构造器中没有显示调用父类的指定构造器,默认调用父类空构造super()

​ 在一个构造器的首行,this()与super()不能同时存在
​ 当存在子父类继承关系下,创建子类对象–>先父类后子类
​ this和super不能使用在static环境中

final

final是最终的意思,既可以修饰局部,也可以修饰成员。

1.被final修饰的变量为常量(标识符的规范)
2.被final修饰的方法不能被重写
3.被final修饰的类不能被继承

Object

我们可以形象的称为“老祖宗类”,它是所有类的父类,也就是说java中的所有类都会直接或间接的继承自Object,同样Object中定义的成员,只要子类有访问权限,都是可以使用的。

下面重点介绍object中的两个重点方法 equals 和 toString

equals

作用是比较两个对象是否相等,但是程序默认比较的是对象的地址,而我们在运用的时候是比较对象的内容,而非地址,因此我们需要对其进行重写

object中的代码:

public boolean equals(Object obj) {
	return (this == obj);
}

重写后的:

@Override
public boolean equals(Object obj) {  
	//增强程序健壮性  先过滤一下如果地址相等,就是一个对象,不需要比较内容
    if(this==obj){
        return true;
    }
    //判断参数是否为null,预防空指针异常
    if(obj!=null){
    	//先把obj从Object类型强转为User类型,因为想要调用 User的成员变量name
    	User other = (User)obj;  //other就是参数对象  强转
    	//如果用户名相等返回true,如果用户名不相等,直接返回false
    	if(this.name.equals(other.name)){
         return true;
        }
    }
    return false;
}
//使用
public static void main(String[] args) {
    User u = new User("zhangsan");  //创建User对象,并调用带参构造器为对象初始化信息
    User u1 = new User("lisi");
    System.out.println(u.equals(u1));//比较内容
    System.out.println(u==u1);//比较地址
}    
    

因此我们在javabean中,如果需要也是要重写equals方法的。我们也可以用alt+insert 快捷键自动生成equals重写方法。

toString

可以将对象以字符串的形式返回,同样返回的也是打印对象的地址,因此也需要我们进行重写,才能返回对象的基本信息

@Override
public String toString() {
    return "姓名-->"+name;
}

return后面想返回什么内容就可以写什么内容,返回的是String 类型的。和equals一样,在javabean中,如果用到也是需要重写方法的,也可以用alt+insert自动重写方法。

多态

定义

多态是一种事物的多种形态|表现形式。是在继承和实现前提下的。

语法 : 父类 引用 = 子类的对象 (父类的引用指向子类的对象)

Parent p = new Child();

多态的调用:如果是成员方法,多态会调用子类重写方法,但子类的新增方法不可见

​ 如果是成员变量,编译和运行都是看父类的

类型转换

在多态的前提下,如果我们想要调用子类的新增内容呢,这就需要用到转型。多态其实也就是自动向上转型。而向下转型和我们之前学到的基本数据类型的转换时一样的,可以叫做强转

上面定义的p是Parent(父类)的,因此我们强转下。Child c = (Child) p;

但是这样写又会遇到一个问题,当Parent 有一个Kid的子类,因为之前多态是指向的Child类的对象,这时我们如果 Kid k = (Kid) p;这样强转,就会遇到类型转换异常

为了解决类型转换异常,我们可以用 一个运算符 instanceof

引用 instanceof 类型: 判断前面的引用指向的对象是否为后面类型的对象,或者前面的引用是否指向后面类型子类的对象,如果是返回true,不是返回false
编译:只检查前面的引用与后面的类型是否在一条继承体系上,如果在编译就不报错,不在编译就报错

System.out.println(p instanceof Child);//true
System.out.println(p instanceof Kid);//false
System.out.println(p instanceof Object);//true 
System.out.println(p instanceof Son);//Child 的子类  false

instence是实例的意思, p instenceof Child 可以理解为p是Child的实例吗?因为本身是指向Child类的,所以是Child的实例。同样也是Child父类的实例。但对于Child是兄弟的Kid以及其儿子Son,p并不是他们的实例。
面向对象是有些抽象的,我们只有多接触才会有更进一步的了解,坚持学习下去,一定会有更多的见解的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值