狂神说JavaSE篇Day08_面向对象

这篇博客详细讲解了Java的面向对象特性,包括类和对象的创建、封装、继承、多态的概念,以及构造器、super关键字、方法重写、类型转换和内部类的相关知识。重点介绍了面向对象编程中的核心概念和实践技巧。

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

一、什么是面向对象

在这里插入图片描述
面向过程:线性思维
面向对象:以类的方式组织代码,以对象的方式组织数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 同一个包指同一层级,即同一目录层级下
  • 子类和父类在同一包下,子类可使用除private外的父类成员;
  • 子类和父类不在同一包下,子类只能使用protected和public的父类成员

二、回顾方法

2.1 方法的定义

  • 修饰符
  • 返回类型
  • break:(跳出switch,结束循环)和return(结束方法,返回结果)区别
  • 方法名:注意规范、见名知意
  • 参数列表:参数类型、参数名,可变长参数
  • 异常抛出:后面讲解

2.2 方法的调用

  • 静态方法(可通过类调用)和非静态方法(只能通过实例调用),static
  • 形参和实参
  • 值传递和引用传递
  • this关键字:代表类的实例,和python中的self类似,this可以提高程序可读性,不写不影响代码执行;this指向实例自身
  • this.什么时候不能省略:用来区分局部变量和实例变量的时候,不能省
    在这里插入图片描述
    在这里插入图片描述

三、类与对象的创建

在这里插入图片描述
在这里插入图片描述

3.1 使用new关键字创建对象

//Student.java
package com.oop.demo01;

//学生类
public class Student {
    //属性
    String name; //默认值null
    int age; //默认值0
    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}

//Application.java
package com.oop.demo01;
//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类实例化后返回一个对象
        //student对象就是Student类的一个具体实例
//        Student student = new Student();
//        student.study();
        Student jack = new Student();
        Student rose = new Student();
        jack.name = "jack";
        jack.age = 11;
        System.out.println(jack.name);
        System.out.println(jack.age);
        System.out.println(rose.name);
        System.out.println(rose.age);
    }
}

3.2 构造器详解

在这里插入图片描述

  • 一个类即使什么都不写,也会存在一个方法;
  • 构造器:名称必须和类名相同;必须没有返回类型,也不能写void,类似python的__init__方法
    在这里插入图片描述
    在这里插入图片描述
    this()等同于调用构造器方法
    在这里插入图片描述
package com.oop.demo01;

public class Person {
    //显式定义构造器
    String name;
    //实例化初始值
    //使用new关键字,本质实在调用构造器
    //无参定义
    public Person(){
        this.name = "default";
    }
    //有参定义;定了有参构造,还想使用无参构造,则需显示定义无参构造
    public Person(String name){
        this.name = name;
    }
}

生成构造器快捷键
在这里插入图片描述

3.3 创建对象内存分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、封装

在这里插入图片描述

在这里插入图片描述
将属性私有化,通过get和set方法访问和修改,在set方法中添加安全性校验
private关键字:私有,只能在类内部访问,类外部无法访问
public:类内部和外部都能访问

package com.oop.demo02;

public class Student {
    //属性私有
    private String name; //名字
    private int age; //年龄
    private char gender; //名字

    //提供一些可以操作属性的方法
    //提供一些public的get、set方法
    public String getName(){
       return this.name;
    }
    public void setName(String name){
        this.name = name;
    }

    public void setAge(int age) {
        if(age>0 && age<100){
            this.age = age;
        }else{
            this.age = 0;
        }
    }
}

在这里插入图片描述
封装的意义:

  • 提高程序的安全性,保护数据
  • 隐藏代码的实现细节
  • 统一接口
  • 提高系统的可维护性

五、继承

在这里插入图片描述

子类继承父类,就会拥有父类的全部方法和属性
<私有的可以继承但无法直接访问!!!!>

5.1 object类

快捷键:ctrl+H
在这里插入图片描述
在java中,所有的类都默认直接或间接继承Object类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2 super详解

在这里插入图片描述

在这里插入图片描述
super注意点:
super()的作用:初始化当前对象的父类特征,并不是创建父类对象
super.关键字代表当前对象的父类型特征
super不是引用,也不保存内存地址,也不指向任何对象
假设子类和父类中出现同名属性,则super不能省略,否则默认为子类属性
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • super仅出现在子类的方法或构造方法中
  • 子类在实例化时,子类构造函数中默认先调用父类的无参构造函数
  • 子类构造方法中如果显式通过super()调用父类的构造方法,必须在第一行
  • super()和this()不能同时出现,因为都必须放在第一行
    在这里插入图片描述

5.3 方法重写

向上转型
添加链接描述
在这里插入图片描述
静态方法方法的调用只和左边定义的数据类型有关
静态方法是类的方法,非静态方法是对象的方法

在这里插入图片描述
在这里插入图片描述
重写总结

  • 需要有继承关系,子类重写父类方法
  • 方法名必须相同,参数列表相同,返回类型要兼容
  • 修饰符:范围可以扩大,但不能缩小;即访问权限不能更严格:public>protected>default>private
  • 抛出的异常:范围可以被缩小,但不能扩大;
  • 方法一样,方法体不同

注意:

  • 私有方法不能继承,所以不能重写
  • 构造方法不能继承,所以不能重写
  • 静态方法不存在重写

为什么需要重写

  • 父类的功能,子类不一定需要或不一定满足
  • Alt+insert ;override
    在这里插入图片描述

六、多态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Student()实例既可以是Student类型,也可以是Person类型;但声明为Person类型,就只能使用Person类的方法

多态注意事项:

  • 多态是方法的多态,属性没有多态
  • 父类和子类。有联系
  • 存在的条件:有继承关系,方法需要重写,父类引用指向子类
  • static方法属于类,不属于实例,无法重写
  • final修饰的,无法重写
  • private修饰的,无法重写
  • 方法中形参声明为父类,实参可以为任意子类对象

七、instanceof和类型转换

7.1 instanceof关键字

含义:判断一个对象是什么类型

  1. X instanceof Y能否编译通过:看对象X的类型(左边)和Y的类型有无父子关系
  2. X instanceofY结果为true还是false:看对象X的引用指向对象(右边)是否为Y的类或子类

编译看左,运行看右!!!

package com.oop;

import com.oop.demo04.Person;
import com.oop.demo04.Student;
import com.oop.demo04.Teacher;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //Object>String
        //Object>Person>Student
        //Object>Person>Teacher
        Object o = new Student();
        System.out.println(o instanceof Student);//true
        System.out.println(o instanceof Person);//true
        System.out.println(o instanceof Object);//true
        System.out.println(o instanceof Teacher);//false
        System.out.println(o instanceof String);//false
        System.out.println("===========================");
        Person p = new Student();
        System.out.println(p instanceof Student);//true
        System.out.println(p instanceof Person);//true
        System.out.println(p instanceof Object);//true
        System.out.println(p instanceof Teacher);//false
       // System.out.println(p instanceof String);//编译报错,Person和String同级,没有联系
        System.out.println("===========================");
        Student s = new Student();
        System.out.println(s instanceof Student);//true
        System.out.println(s instanceof Person);//true
        System.out.println(s instanceof Object);//true
//        System.out.println(s instanceof Teacher);//编译报错
//        System.out.println(s instanceof String);//编译报错
        System.out.println("===========================");
        Person per = new Person();
        System.out.println(per instanceof Student);//false
        System.out.println(per instanceof Person);//true
        System.out.println(per instanceof Object);//true
    }
}

7.2 类型转换

package com.oop;

import com.oop.demo04.Person;
import com.oop.demo04.Student;
import com.oop.demo04.Teacher;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类型之间转换:父<====>子
        //            高<====>低
        Person p = new Student();
        //将p这个对象转成Student类型,高转低,需要强转
//        Student s = (Student) p;
        ((Student) p).eat();

        Student s2 = new Student();
        //将s2这个对象转成Person类型,低转高,自动转换
        //子类转成父类,可能丢失自己本来的一些方法
        Person p2 = s2;
    }
}

总结:

  • 父类引用指向子类对象
  • 把子类转成父类,向上转型;可能丢失子类中特有方法
    • 把父类转成子类,向下转型,需要强制转换,可能丢失父类中私有方法

八、static关键字详解

package com.oop.demo05;
//static
public class Student {
    private static int age;//静态变量
    private double score;//非静态变量
    public  void run(){
        System.out.println("running");
        eat(); //非静态方法中可以调用静态方法;
    }
    public static void eat(){
        System.out.println("eating");
        //run();静态方法中不可直接调用非静态方法
    }
    public static void main(String[] args) {
        Student s = new Student();
        System.out.println(s.score);
        System.out.println(s.age);
        System.out.println(Student.age);

        Student.eat();
        eat();
        s.run();
        s.eat();
    }
}

在这里插入图片描述
在这里插入图片描述

package com.oop.demo05;

public class Person {
    //匿名代码块,第二个执行
    {
        System.out.println("匿名代码块");
    }
    //静态代码块,第一个执行,只执行一次
    static {
        System.out.println("静态代码块");//静态代码块中只能使用static修饰的属性和方法
    }
    //第三个执行
    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person = new Person();
        System.out.println("============");
        Person person2 = new Person();
    }
}

九、抽象类

在这里插入图片描述

package com.oop.demo06;
//abstract 抽象类
public abstract class Action {

    //abstract 抽象方法:只有方法名字,没有方法实现
    public abstract void doSomeThing();
}

======================================
package com.oop.demo06;
//抽象类的子类,需要实现抽象类的抽象方法,除非子类也是抽象类
//extend:单继承,接口可以多继承
public class Test01 extends Action{
    @Override
    public void doSomeThing() {

    }
}

特点:

  1. 不能new抽象类,只能靠子类实现
  2. 抽象方法必须在抽象类中
  3. 抽象类中可以有普通方法
  4. 抽象的抽象:约束
    在这里插入图片描述
    在这里插入图片描述

十、接口的定义和实现

在这里插入图片描述

package com.oop.demo07;

//interface关键字,接口都需要有实现类
public interface UserService {
    //默认是常量
    int AGE = 10;
    //接口中的所有定义都是抽象的,默认public abstract
    void addName(String name);
    void deleteName(String name);
    void updateName(String name);
    void queryName(String name);
}

========================================

package com.oop.demo07;
//类实现接口,implements 接口
//实现了接口的类,就需要重写接口中的方法
//利用接口实现多实现
public class UserServiceImpl implements UserService,TimeService {
    @Override
    public void addName(String name) {

    }

    @Override
    public void deleteName(String name) {

    }

    @Override
    public void updateName(String name) {

    }

    @Override
    public void queryName(String name) {

    }

    @Override
    public void timer() {

    }
}


作用:

  1. 约束;
  2. 定义一些方法,让不同人实现
  3. 方法修饰符默认都是public abstract
  4. 属性修饰符默认都是public static final,不需要显示写
  5. 接口不能直接实例化 ,接口中没有构造方法
  6. 接口可以继承其他接口
  7. implements可以实现多个接口
  8. 实现接口的类必须提供接口中所有方法的具体实现内容(即重写),方可实例化,否则仍为抽象类
  9. 如果一个类即继承父类,又实现接口;那么先继承,再实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

十一、N种内部类

内部类的主要作用:解决类的多重继承问题
在这里插入图片描述

11.1 成员内部类

package com.oop.demo08;

public class Outer {
    private int id=10;
    public void out(){
        System.out.println("这是外部类的方法");
    }
    public class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }
        //获得外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
    }
}
======================================

package com.oop;

import com.oop.demo04.Person;
import com.oop.demo04.Student;
import com.oop.demo04.Teacher;
import com.oop.demo08.Outer;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }
}

11.2 静态内部类

package com.oop.demo08;

public class Outer {
    private int id=10;
    public void out(){
        System.out.println("这是外部类的方法");
    }
    public static class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }
    }
}

11.3 局部内部类

package com.oop.demo08;

public class Outer {
    private int id=10;
    public void method(){
        //局部内部类,定义在方法中
        class Inner{
        }
    }
}

11.4 匿名内部类

package com.oop.demo08;

public class Outer {
    private int id=10;

    public static void main(String[] args) {
        //没有名字初始化类,不讲实例保存到变量中
        new Apple().eat();
    }

}

class Apple{
    public void eat(){
        System.out.println("eeee");
    }
}

在这里插入图片描述

一个java文件中最外层可以有多个class,但只能有一个public class
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值