面向对象

  • Java 是面向对象的编程语言,对象就是面向对象程序设计的核心 那问题来了 什么是对象?(这问题问的好)

    • 你家猫 你家狗 你家桌子 你家的所有东西都可以称为对象 现实世界的一切 人 动物 皆为 “对象”
  • 类与对象:

    • 类:是一种分类 他描述一类对象的行为和状态 特征。具有相同特性与行为的事物集合
    • 对象:一个个性产物,是一个个体的特征,是类的一个实例 有状态和行为
  • 面向对象的三大核心特性:

    • 封装:对外部不可见

      • 属性的封装、方法的封装、类的封装、组件的封装、模块化封装、系统级封装…
      • 模块化、信息隐藏、复用、具有安全性
    • 继承:扩展类的功能

      • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
      • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
    • 多态:方法的重载 对象的多态性

      • 编译看左边 运行看右边
      • 提高了代码的复用性(由继承保证)
      • 提高了代码的扩展性(由多态来保证)

面向对象的创建和使用

public class Student {
    String name;

    int age;

    public void add(){
        System.out.println(this.name + "在学习");
    }
}
public class Application {
    public static void main(String[] args) {
        Student s = new Student(); //s = this
        s.age = 18;
        s.name = "张三";
        s.add();

        Student s1 = new Student(); //s1 = this
        s1.age = 15;
        s1.name = "李四";
        s1.add();

        //this = 当前对象

        System.out.println(s == s1); //false  内存地址不相同 好比是张三在学习 李四在学习 不是同一个人在学习

    }
}
  • this表示当前类中的对象

成员变量和局部变量

public class dog {
    String name;

    int age; //成员变量

    public void show(int age) {  //局部变量
        age++;
        System.out.println(age);

        System.out.println(this.age); //输出的是成员变量 因为加了this
    }
}
public class Demo {
    public static void main(String[] args) {
        dog dog = new dog();
        dog.show(10);
        //输出的是局部变量的值  输出11 0

        
        dog.age = 20;
        dog.show(10);
        //输出11  20
    }
}
  • 成员变量:类中方法外、堆内存、有初始值、随着对象存在而存在消失而消失
  • 局部变量:方法内、栈内存、无初始值、随着方法而存在 消失而消失

构造方法

public class Student {
    String name;

    int age;

    public Student() {
        System.out.println("实例化的时候默认提供无参构造方法");
    }
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println(name + age);
    }
}
public class Application {
    public static void main(String[] args) {
        new Student(); //实例化的时候默认提供无参构造方法

        new Student("张三",15); //张三15
    }
}
  • 如果在学生类里面先定义了有参数的构造方法 不定义无参数的构造方法 在测试调用的时候无参构造方法无法调用

面向对象封装

public class Student {

    //封装    属性私有化
    private String name;
    private  int age;

    //提供无参和有参数的构造方法
    public Student() {

    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //属性私有化以后提供get 和set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("张三");
        student.setAge(15);


        System.out.println(student.getName());
        System.out.println(student.getAge());
    }
}
  • 创建的时候 属性私有化 创建set和get方法进行访问
  • 属性封装完成后 访问会比较安全

面向对象继承

public class Student extends Person{}
public class Person {
    private  String name;
    private int age;

    public void eat(){
        System.out.println(name + "在吃东西");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.setAge(18);
        student.setName("张三");
        
        student.eat();
        //Student继承person以后就可以拿到eat的方法
        //    person属性是私有化 需要提供set和get方法才能供Student使用
    }
}
  • 继承就相当于儿子继承爸爸、 父子类、猫、狗 继承动物等等
  • 可以单继承 不可以多继承(一个爸爸有多个儿子) 可以多重继承(儿子继承爸爸、爸爸继承爷爷) 祖传三代 B继承A C继承B等
  • Object是老祖宗类、在java当中所有的类都间接继承Object类

super关键字

public class Student extends Person{
    String name = "Student";

    public Student() {
        System.out.println("Student无参执行.");
    }
    public void add(String name){
        System.out.println(name); //张三
        System.out.println(this.name); //Student
        System.out.println(super.name); //Person
    }
}
public class Person {
    String name = "Person";

    public Person() {
        System.out.println("Person无参构造执行.");
    }
}
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.add("张三");
        //Person无参构造执行.
        //Student无参执行.
        //张三
        //Student
        //Person
    }
}
  • this 没有继承也可以使用
  • super 只能在继承的条件下使用 只能出现在子类的方法 构造器中
  • super和this不能同时调用构造方法

抽象类

//抽象类
public abstract class Animal {

    //抽象方法
    public abstract void test();

    public void add(){
        System.out.println("成员方法");
    }
}
  • 不能实例化
  • 抽象类 可以写普通方法 抽象方法必须在抽象类中
  • 有抽象方法的类必须是抽象类 抽象方法没有方法体
  • 约束
  • 抽象方法必须在子类中被实现 除非子类是抽象类
  • 把公共的东西抽象出来 提高开发效率 供子类使用
public abstract class Animal {

    //抽象方法
    public abstract void eat();
    public abstract void sleep();
}
public class dog extends Animal{
    String name;

    @Override
    public void eat() {
        System.out.println(name +"吃饭");
    }

    @Override
    public void sleep() {
        System.out.println(name + "睡觉");
    }
}
public class Demo {
    public static void main(String[] args) {
        dog d = new dog();
        d.name = "小狗";
        d.eat();  //小狗吃饭
        d.sleep(); //小狗睡觉
    }
}
  • dog继承Animal抽象类 那dog每天必须要做的事情就是吃饭和睡觉 把公共的东西抽象出来 提高开发效率 供子类使用

面向对象多态

  • 实现思路

    • 继承
    • 子类重写父类
    • 父类引用指向子类
  • 访问方式

    • 成员变量:编译看左边 (父类) 运行看左边(父类)
    • 方法:编译看左边(子类) 运行看右边(子类)
public class Cat extends Animal{
    public void eat(){
        System.out.println("小猫在吃猫粮");
    }
    public void sleep(){
        System.out.println("小猫在睡觉");
    }
}
public class Animal {

    public void eat(){
        System.out.println("动物在吃饭");
    }

}
public class Test {
    public static void main(String[] args) {
        //向上转型
        Animal a = new Cat();
        //只能调用吃的方法 不能调用子类睡觉的方法
        a.eat(); //小猫在吃猫粮


        //向下转型 需要向上转型后才能使用向下转型
        Cat c = (Cat) a;
        //调用子类睡觉的方法
        c.sleep();  //小猫在睡觉
    }
}
  • 成员变量:编译看左边 (父类) 运行看左边(父类)
  • 方法:编译看左边(子类) 运行看右边(子类)

instanceof运算符

  • 判断引用指向的对象类型
public class Cat extends Animal{
    public void eat(){
        System.out.println("小猫在猫粮");
    }
    public void sleep(){
        System.out.println("小猫在睡觉");
    }
}
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("小狗在吃饭");
    }
    public void sleep(){
        System.out.println("小狗在睡觉");
    }
}
public class Animal {
    public void eat(){
        System.out.println("动物在吃饭");
    }
}
public class Test {
    public static void main(String[] args) {
        //向上转型
        add(new Cat()); //小猫在猫粮
        add(new Dog()); //小狗在吃饭

        System.out.println("===================");
        //向下转型
        show(new Cat()); //小猫在睡觉
        show(new Dog()); //小狗在睡觉
    }

    public static void add(Animal animal){
        animal.eat();
    }

    /*
     * 当在调用这个方法的时候 判断传入的参数
     * 如果是Cat 则会判断animal是否是指向Cat
     * 如果指向Cat就进行向下转型
     */
    //微妙之处:通过instanceof进行判断更加方便
    public static void show(Animal animal){
       if (animal instanceof Cat) {
           Cat c = (Cat) animal;
           c.sleep();
       } else if (animal instanceof Dog) {
           Dog d = (Dog) animal;
           d.sleep();
       }
    }
}

接口

什么是接口

  • 一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

接口的特点

  • 接口中的每个方法都是隐式抽象的,接口中的方法会被隐式的指定为public abstract
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final变量
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法

接口和类的区别

  • 接口不能实例化
  • 接口没有构造方法
  • 接口中所有的方法必须是抽象方法,java8之后可以使用default关键字修饰非抽象方法
  • 接口不能包含成员变量,除了static和final变量
  • 接口支持多实现

接口和抽象类的区别

  • 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不能有方法体
  • 抽象类中的成员变量可以使各种类型的,而接口中的成员变量只能是public static final类型的。
  • 接口中不能含有静态代码块以及静态方法,而抽象类中可以有静态代码块和静态方法。
  • 一个类只能继承一个抽象类,而一个类可以实现多个接口。
public interface caidan {
    //无法实例化
    //都是抽象方法
    void jiaozi();
    void miantiao();
}
//厨师类实现了这个接口要做不同的饭
public class chushi implements caidan{
    @Override
    public void jiaozi() {
        System.out.println("韭菜鸡蛋");
    }

    @Override
    public void miantiao() {
        System.out.println("西红柿面条");
    }
}
public class Demo {
    public static void main(String[] args) {
        chushi c = new chushi();
        c.jiaozi(); //韭菜鸡蛋
        c.miantiao(); //西红柿面条
    }
}

常量

  • final 必须手动赋值;
  • final 修饰的类无法被继承;
  • final 修饰的方法无法被覆盖;
  • static final 联合使用为常量
public class FinalTest {

    public static void main(String[] args) {
        System.out.println(user.Guo_ji);
        System.out.println(user.age);
        System.out.println(user.name);
    }
}
final class user{
    static final String Guo_ji = "中国"; //常量
    public static final int age = 15; //公开常量

    static String name = "张三";//静态
}

访问控制权限

访问权限同类同包非同包子类非同包非子类
×
×××
××××
最后修改:2023 年 03 月 30 日
如果觉得我的文章对你有用,请随意赞赏