java 面向对象

java 面向对象

面向对象(Object Oriented Programming OOP)

初识面向对象

以类的方式组织代码,以对象的组织封装数据。

对象的创建分析

对象的创建必须通过 new 方法实现。

new 方法的本质就是调用构造器。

构造器

作用:

  1. 初始化对象

规则:

  1. 必须和类同名
  2. 没有返回值

**注意点:**当定义有参构造器后,若想使用无参构造器,则必须进行显式定义一个无参构造器。

public class student{
    String name; // 属性
    // 若不定义构造器,则会默认有一个无参构造器
    public student(){ // 无参构造器
        
    }
    public student(String name){ // 有参构造器
        this.name = name;
    }
}
// IDEA 中可以使用 Alt + Insert 快捷键创建构造器

面向对象三大特性

封装

程序设计中追求“高内聚,低耦合”,高内聚是指类的内部数据操作细节由自己来完成,不允许外部干涉;低耦合是指仅仅暴露少量的方法供外部使用。

简单来说就是“属性私有,get/set”

// Pet 类
public class Pet {
    // 测试 java 封装特性
    // 属性私有: private
    private String name;
    // get/set : 快捷键 Alt + Insert
    // 也可选中 Code 选项卡中的 Generate 选项,选择Getter and Setter

    // 无参构造器
    public Pet() {
    }
    // 有参构造器,当定义了有参构造器后,想调用无参构造器必须显示定义无参构造器
    public Pet(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
}
// 主程序,测试 Pet 类
public class Demo1 {
    public static void main(String[] args) {
        Pet p1 = new Pet();
        System.out.println(p1.getName());
        Pet p2 = new Pet("旺财");
        System.out.println(p2.getName());
    }
}

封装的作用

  1. 提高了系统的安全性,保护数据
  2. 隐藏了实现细节
  3. 统一接口
  4. 增强了系统的可维护性

继承

java 中只有单继承,没有多继承

当多个类存在相同属性和行为时,可将这些内容抽取到单独一个类中,则多个类无需再定义这些属性和行为,只需要继承该类即可。被继承的类称之为父类,继承的类称之为子类。关键字 extends

public class Dog extends Pet{
    // Pet 为父类, Dog 为子类
    // 子类可直接访问父类中的 非私有 的属性和方法
}

继承的作用

  1. 提高了代码的复用性
  2. 使得类与类之间产生了关系,是多态的前提

注意事项

​ 只有当类之间存在着 is a 的关系时,考虑使用继承。不要为了继承部分 功能,而去使用继承。

super 和 this 的区别
  1. 代表的对象不同,super关键字,代表父类的存储空间标识,是父类的引用;this 关键字代表对象的应用(谁调用就代表谁。
  2. 使用场景不同,当子父类出现同名成员时,可以用 super 进行区分;当子类要调用父类构造函数时,可以使用super语句。

注意事项

​ 当子类对象初始化时,默认在子类的构造函数第一行调用了super()。

// Dog 类 继承 Pet 类
public class Dog extends Pet{
    private int age;
    // 当使用 ALt + Insert 快捷键生成子类的构造器时,会先提示选择父类的构造器,再选择子类的。
    public Dog(String name, int age) {
        super(name);
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Pet p1 = new Pet();
        System.out.println(p1.getName());
        // 父类引用可以指向子类对象
        Pet p2 = new Dog("大花",3);
        // 但由于父类中没有 getAge(),故此处报错
        // 能调用什么方法和左边有关,和右边没有关系。
        System.out.println(p2.getAge());
    }
}

扩展

IDEA 中在类中使用快捷键 Ctrl + H 可看到类的继承关系树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NJ4VzKZG-1658056067059)(java 面向对象.assets/image-20220717162408494.png)]

方法的重写

子类中出现和父类一模一样的方法时(返回值类型,方法名,参数列表都要相同),会出现覆盖操作,称之为重写。

注意事项

  1. 父类的私有方法,子类看不到,因此父类的私有方法不存在重写。
  2. 重写时,子类方法的权限一定要大于等于父类方法权限。public >protected >default >private
  3. 抛出的异常:范围可以缩小,不能被扩大。
  4. 重写用在子类需要父类的功能,同时又有自己特有的内容时。
  5. 静态方法只跟类有关,不存在重写。
子父类构造方法的用法
  1. 在初始化子类对象时,首先执行父类的初始化动作,但不会初始化一个父类对象,子类的构造方法中默认有一个super()。
  2. 如果父类没有无参构造方法,则可使用super调用父类的有参构造方法(推荐方式)
  3. 也可使用 this 调用本身的其他构造。this() 和 super() 都是在构造函数的第一行,不能同时出现。
静态代码块、构造代码块,构造方法的执行顺序

父类静态代码块->子类静态代码块->父类构造代码块->父类构造方法->子类构造代码块->子类构造方法

static{
    // 静态代码块,类加载时执行一次
}
{
    //构造代码块,每次对象实例化时调用一次,
}

多态

定义

对象在不同时刻表现出来的不同状态

多态的前提

  1. 要有继承(类)或实现(接口)关系
  2. 要有方法的重写
  3. 要有父类引用指向子类对象

在程序中的体现

父类或接口的引用指向或者接收自己的子类对象

多态的作用

提高了程序的扩展性和可维护性

多态的弊端

父类调用的时候只能调用父类中的方法,不能调用子类中特有的方法,因为并不清楚哪个子类会继承该父类。

多态成员的特点

  1. 变量:编译和运行都看等号左边
  2. 方法:编译看左边,运行看右边
  3. 静态方法:编译和运行都看左边

不能将父类对象转换为子类类型

父类的引用指向子类对象,该引用可以被提升,可以强制转换。

多态中变化的是子类对象。

// Pet 父类 Dog 子类
{ // 正确
    Pet pet = new Dog(); // 父类引用指向子类对象,向上提升
    Dog d1 = (Dog)pet; // 向下转换
}
{ // 错误
    Pet pet = new Pet()
    Dog d1 = (Dog)pet;   // 父类对象不能转换
}

抽象类和接口

抽象类

Java 中可以定义没有方法体的方法,该方法的具体实现由子类完成,这种方法称之为抽象方法,包含抽象方法的类必须定义为抽象类。

抽象类中也可以由正常的方法定义。

应用场景

多个对象具有相同的功能,但功能的具体内容有所不同,在抽象的过程中,只抽象功能定义,不抽象功能主体,即只有功能声明,没有功能主体。

注意点

  1. 抽象类和抽象方法必须被 abstract 关键字修饰

  2. 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。

  3. 抽象类不能使用 new 方法创建对象,但有构造函数,所有类中都有构造函数

  4. 抽象类中的抽象方法要被使用,必须通过子类实现,然后通过子类对象调用。

  5. 若一个类继承了抽象类,则该类要么为抽象类,要么实现了所继承类的所有抽象方法。

    public abstract class abstract_demo { // 抽象类
        public abstract void say(); //抽象方法
        
        public  void  shout(){
            System.out.println("汪汪");
        }
    }
    

    当写一个类继承该抽象类时,IDEA会自动提示重写里面所有的抽象方法。

    接口

    接口本质上是一种特殊的抽象类,只包含常量和方法的定义,没有变量和方法的实现。使用关键字 interface 定义

    特点

    1. 不能被示例化
    2. 没有构造方法
    3. 一个类如果实现了接口,要么是抽象类,要么实现了接口中的所有方法
    4. 能被类实现(implement),class 类名 implements 接口名(可多个){}
    5. 类与接口之间是实现关系,接口与接口之间是继承关系,并且接口可以多继承,一个类也可以实现多个接口。还可以在继承一个类的同时实现多个接口 (className) extends (className) implements (interface1,interface2)
    6. 接口中成员修饰符是固定的,成员常量:public static final ,成员方法:public abstract ,且可以省略。(推荐 手动给出修饰符)

    接口的思想

    1. 接口是对外暴露的规则
    2. 接口是程序的功能扩展
    3. 接口的出现降低了耦合性(实现模块化开发,每个人实现对应的接口即可,提高了开发效率)
    4. 一个类可以实现多个接口
    5. 多个类也可以实现同一个接口
    public interface interface_demo {
        public abstract void say();
    }
    

内部类

内部类

将一个类定义在另外一个类里面,里面的类称之为内部类。

特点

  1. 内部类是外部类的一个成员,所以内部类可直接访问外部类的成员,包括私有成员。
  2. 内部类仍是一个独立的类,会编译成独立的class文件,但会在前面冠以外部类的类名和$符号。

分类

  1. 成员内部类

    • 定义在类中方法外的类
    • 创建对象的格式为:外部类名.内部类名 对象名 = 外部类对象.内部类对象
  2. 静态内部类

    • 成员内部类加上静态修饰符

    • 内部类静态成员,可创建对象访问,也可以直接访问,非静态成员,必须通过创建对象访问。

  3. 局部内部类

    • 定义在方法中的类
    • 只能在定义的方法内实例化
    • 不能使用定义的方法中非final局部变量
    • 静态方法中的方法内部类只能访问外部的静态成员
  4. 匿名内部类

    实现一个带内容的外部类或接口的子类匿名对象

    格式:new 外部类名或接口名{}

    一个 java 文件中可以有多个类但只能有一个 public 类

    
    public class test{
        public static void main(String[] args) {
            // 没有名字初始化类
            new Apple().say(); // 这就是一个匿名内部类
            new interface1(){  // 相当一个实现接口的类
                @Override
                public void shout() {
                }
            };
        }
    }
    class Apple{
        public void say(){
            System.out.println("这是一个苹果");
        }
    }
    interface interface1{
        public abstract void shout();
    }
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值