JavaSE-面向对象(总结复习详细)

前言:

在 Java SE 中,面向对象编程是一种基本的编程范式,它将现实世界中的问题抽象成对象,然后通过对象之间的交互来解决问题。在面向对象编程中,所有的操作都是围绕对象展开的,对象拥有属性和行为,并且可以通过封装、继承和多态等特性来实现代码的重用和扩展。

面向对象编程的核心概念包括:

  1. 类(Class):类是对象的模板,定义了对象的属性和行为。通过类可以创建具体的对象。
  2. 对象(Object):具体的实例化对象,每个对象都有自己的属性和行为。
  3. 封装(Encapsulation):将数据和操作封装在一个类中,通过对外提供接口来访问对象的内部状态,从而保护对象的数据安全性。
  4. 继承(Inheritance):允许一个类继承另一个类的属性和行为,并且可以扩展或修改这些特性。
  5. 多态(Polymorphism):允许不同的对象对同一个消息做出自己的响应,提高代码的灵活性和可扩展性。

在 Java SE 中,面向对象编程是一种强大且灵活的编程范式,通过合理地运用面向对象的思想,可以更好地组织和管理代码,提高代码的可维护性和可扩展性

面向过程(POP)

 面向过程的程序设计思想

关注的焦点是过程:过程就是操作数据的步骤。如果出现代码重复 就会封装为一个函数.这样就可以大大简化代码,便于维护。

典型的语言:c语言

代码结构:以函数为组织单位

面向过程适合解决简单问题,分析出解决问题的所需步骤,然后一步一实现。

缺点:扩展能力差、后期维护难度较大。

面向对象(OOP)

面向对象的程序设计思想

关注的焦点是:在计算机程序设计过程中,参照现实中事物,将事物的属性特征,行为特征抽象出来,用类来表示(个人理解:类就是将一个事物的所有功能提前写成代码实现,后面只需要调取并且填去关键的信息就可以是实现)

典型的语言:Java、C#、C++、Python、Ruby和PHP等

代码结构:以类为组织单位。每种事物都具备自己的属性和行为/功能

是一种设计者思维,适合解决复杂问题。代码扩展性强、可维护性高

1))普通类(类共有)

1.类的定义

类:具有相同特征(同一类)事物的抽象描述,先根据客观事物进行抽象(设计程序),然后由抽象创造出具体,最终使用的是具体.

类的简单理解:类可以看做一个模版,例如:作文模版-->我们只需要在模版上修改,添加自己的意愿就变成一个十分完美的自己的作文.而类是一类事物的模版,我们需要实现这个事物(对象-->实现一个类便是创建一个对象),我们只需要对这个类修改,添加自己的意愿便可以得到自己所需.

类的声明格式:

[访问权限修饰符][修饰符]class 类名{
 
}
 
//例如:public class Cat{}

访问权限修饰符:  1.public(公共)   2.无

修饰符:final(修饰的类不能被继承),abstract(修饰抽象类)

关键字:class--->用来定义一个类

类名:遵循java类名规范--->类名首字母大写,见名知意,驼峰表示

2.类的中的成员

成员变量

声明格式:

[访问修饰符] [static] [final] [数据类型] 变量名 [= 初始值];

示例:

public class Person {
    private String name;
    public static int count = 0;
    protected final int age = 30;
    int salary = 50000;
}

成员变量的理解:

  1. 成员变量是定义在类中,方法体之外的变量
  2. 修饰成员变量的数据类型可以是任何数据类型(基本类型,引用类型)
  3. 定义成员变量时,可以赋值也可以不赋值(系统会默认赋值)
  4. 成员变量可以被类中的方法,构造方法,特定方法的语句块访问
  5. 成员变量的作用范围为整个类体

成员方法

声明格式:

[访问修饰符] [修饰符] [返回类型] 方法名(参数列表) {
    // 方法体
    // 可以包含一系列的语句和逻辑
    // 可选的 return 语句
}

方法名:见名知意

参数:外界调用方法需要传进来的变量(类似c语言等编程语言的参数)

示例:

public class MyClass {
    
    // 成员方法的声明
    public int add(int a, int b) {
        return a + b; // 返回两个整数的和
    }
    
    // 成员方法的声明,没有返回值
    private void printMessage(String message) {
        System.out.println(message); // 打印消息
    }
    
    // 成员方法的声明,没有参数也没有返回值
    void greet() {
        System.out.println("Hello, World!"); // 打印问候语
    }
    // static 方法示例
    public static void staticMethod() {
        System.out.println("This is a static method.");
        // 可以在这里编写方法的具体实现
    }
    // final 方法
    public final void finalMethod() {
        System.out.println("This is a final method.");
        // 可以在这里编写方法的具体实现
    }
}

 访问权限修饰符:

  1. public :公共权限 修饰类、属性、方法。可以在任意类中访问
  2. protected:受保护的权限 修饰属性、方法。可以在同包类访问,如果 不是同包类,必须是该类的子类才可以访问。
  3. default:同包权限 修饰类、属性、方法。只能在同包的类访问
  4. private:私有权限 修饰属性、方法。 只能在本类中访问

修饰符:

  1. static  静态的(1.该类的该成员变量在类生成的时候也同时生成,该类所实现的对象公用一个变量--->从地址角度解释:该成员变量只生成一个地址,所用的对象公用该地址的变量 2.static修饰的方法也是在类的生成时,就已经生成,被static修饰的方法不需要实现类对象可以直接调用
  2. final    常量修饰符(1.被final修饰的量,量值不可以修改 2.被final修饰的方法不可以被重写)

      下文会对static与final专门解释

数据类型(返回类型):

       基本类型(八个基本类型)与引用类型()------>下文会有专门的解释

2)抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.

简单理解:一个国家需要做手机,但是他们并不知道手机内部功能具体怎么实现.只知道手机是由屏幕,电池,主板等部件构成.这时国家只需要定义有一个手机类(抽象类),类中有:屏幕,电池,主板等部件(成员方法),具体实现由企业完成(需要实现类的人).

  1. 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和 构造方法。
  2. 用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须 定义成抽象类。

特点:

  1.  抽象类不能被实例化,但可以有构造方法,因为抽象类中含有无具体实现的方法, 所以不能用抽象类创建对象。
  2.  抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样.否则,该类也必须声明为抽象类。

注意:

  1. 抽象方法只能出现在抽象类中
  2. 抽象类中可以定义普通方法
// 抽象类 Animal
abstract class Animal {
    private String name;
    private int age;
    
    // 构造方法
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 普通方法
    public void introduce() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
    
    // 抽象方法
    public abstract void makeSound();
}

3)内部类

1.成员内部类

直接定义在类中,未被static定义的类,就是成员内部类

3. 成员方法能访问静态域  不能拥有静态域(无法定义静态变量);静态方法能访问静域  

 不能访问成员域

       对于成员内部类,不能定义一个静态属性的,因为内部类必须要依赖于外部类,若成员内部类有静态方属性,那么没有外部类对象也能被访问了。

       对于外部类来说,不能在外部类的静态方法中使用成员内部类。比如在外部类的main方法中创建内部类对象

1.成员内部类的特点:

  1. 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
  2. 同名的属性名/方法名访问外部类时 → 外部类.this.成员名
  3.  成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。所以在外部类访问内部类的时候必须先实例化外部类对象

2. 成员内部类对象的创建

成员内部类依赖于外部类的对象,需要先创建外部类的对象,然后通过外部类对象创建内部类对象

public class OuterClass {
    class InnerClass {
        // 成员内部类的成员
    }

    public static void main(String[] args) {
        OuterClass outerObj = new OuterClass();
        InnerClass innerObj = outerObj.new InnerClass();
    }
}

3.成员内部类不能定义静态变量,静态方法但是可以访问静态方法,静态变量(成员内部类未被static修饰

2.静态内部类
直接定义在类中,被static定义的类,就是静态内部类

1.静态内部类特点:

  1. 静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static;
  2. 静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法;
  3. 静态内部类中即能声明静态成员也可以声明非静态成员

2.静态内部类的调用

成员内部类依赖于外部类的对象,需要先创建外部类的对象,然后通过外部类对象创建内部类对象。例如:

public class OuterClass {
    class InnerClass {
        // 成员内部类的成员
    }

    public static void main(String[] args) {
        OuterClass outerObj = new OuterClass();
        InnerClass innerObj = outerObj.new InnerClass();
    }
}
3.局部内部类

编写在方法的内部的类称之为局部内部类,也可以称为方法内部类

1.局部内部类的特点

  1. 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
  2. 局部内部类不可使用权限修饰符静态(static)修饰符进行修饰同局部变量相同;
  3. 局部内部类可以直接访问方法中的属性;
  4. 局部内部类 可以直接访问方法外部类中属性和方法;
  5. 局部内部类 创建对象 要在方法内部 局部内部类的外部声明

2.局部内部类的调用

public class OuterClass {
    public void method() {
        class LocalInnerClass {
            // 局部内部类的成员
        }

        LocalInnerClass localInnerObj = new LocalInnerClass();
    }
}

4)匿名类

匿名类其实也是内部类的一种--->匿名内部类

匿名内部类特点:

  1. 匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
  2. 必须继承一个抽象类或者实现一个接口
  3. 没有构造方法

实现:

// 定义一个接口
interface Greeting {
    void greet();
}

// 创建一个类,并在其中使用匿名内部类实现接口
public class AnonymousInnerClassExample {
    public static void main(String[] args) {
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("Hello, this is an anonymous inner class!");
            }
        };
        
        greeting.greet();
    }
}

总结:

  1. 匿名类是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象。
  2. 匿名类可以继承父类的方法也可以重写父类的方法。
  3. 使用匿名类时,必然是在某个类中直接用匿名类创建对象,以此,匿名类一定是内部类。
  4. 匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法。
  5. 由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法。

对象

对象:以一个为模版,在内存中创建了一个实际存在的实例.

1)创建对象

Car bm= new Car();

Car bm:使用Car类作为类型声明一个变量bm.(生成一个放对象的空间->可以类似于 int a = 10理解)

new Car():使用new 创建对象,然后调用Car类的构造方法初始化对象.(创建对象)

= :将右边创建的对象地址赋给左边的bm变量

理解:

  1. 右边的“new Car()”,是以Car类为模板,在堆空间里创建一个Car类对象
  2. 左边的“Car bm”创建了一个Car类型引用变量。所谓Car类的引用,就是以后可以用来指向Car对象的对象引用。
  3. ”=”操作符使对象引用指向刚创建的那个Car对象。

2)对象使用

对象是类的一个实例,必然具备该类事物的属性和行为(即方法)。

使用对象名.属性或对象名.方法的方式访问对象成员(包括属性和方法)

代码演示:

public class Person {
    private String name;

     //构造方法对成员变量赋值
    public Person(String name) {
        this.name = name;
    }

    //成员方法
    public void introduce() {
        System.out.println("Hello, my name is " + name + ".");
    }

    public static void main(String[] args) {
         //创建person对象
        Person person = new Person("Alice");
        //调用person对象中的introduce方法
        person.introduce();
    }
}

总结类和对象

类是一类事物的抽象概念,是一个模型

对象是由这个模型所创造的,一个个具体存在的,实实在在存在的实例. 所以创建对象的过程也叫实例化对象.

现实生活中先有对象后有类,而编程时先设计类后创建对象(现实我们是根据一个个事,抽象出类.但是编程中的问题,我们已经在现实中抽象出了,所以我们先写类,然后对一个个事实例化)

构造方法

构造方法是写在类中的方法,但是该方法方法名与类名一致并且不需要void修饰

作用:初始化成员变量的值

特点:

  1. 每个类都有构造方法(如果未编写,系统会提供默认的构造方法)
  2. 构造方法分为:无参构造方法与有参构造方法
  3. 一个类可以拥有多个构造方法
  4. 在类的实例化(创建对象)时,就已经运行了

代码演示:

public class MyClass {
    private int value1;
    private String value2;

    // 无参构造方法
    public MyClass() {
        // 可以在这里初始化默认值
        this.value1 = 0;
        this.value2 = "default";
    }

    // 多参数构造方法
    public MyClass(int value1, String value2) {
        this.value1 = value1;
        this.value2 = value2;
    }

    public MyClass(int value1){
        this.value1 = value1;
    }
    public static void main(String[] args) {
        // 使用无参构造方法创建对象
        MyClass obj1 = new MyClass();

        // 使用多参数构造方法创建对象
        MyClass obj2 = new MyClass(10, "hello");


        MyClass obj3 = new MyClass(20);
        // 可以访问对象的属性值
        System.out.println("obj1: " + obj1.value1 + ", " + obj1.value2);
        System.out.println("obj2: " + obj2.value1 + ", " + obj2.value2);
        System.out.println("obj3: " + obj3.value1 + ", " + obj3.value2);
    }
}

运行结果演示:

注意:上面构造方法中一个为只有一个参数的,一个为二个参数的这里涉及到一个知识方法重载

方法重载

方法的重载是指一个类中具有相同的名字,但参数不同的多个方法

参数不同(可以有三方面的不同)

  1. 数量不同
  2. 类型不同
  3. 顺序不同 

调用时,会根据不同的参数表选择对应的方法。

注意:方法重载跟方法的返回值类型没有任何关系

代码演示:

public class OverloadExample {
    // 方法重载:参数数量不同
    public void display(int number) {
        System.out.println("Displaying integer: " + number);
    }

    public void display(int number1, int number2) {
        System.out.println("Displaying integers: " + number1 + " and " + number2);
    }

    // 方法重载:参数类型不同
    public void display(double number) {
        System.out.println("Displaying double: " + number);
    }

    public void display(String text) {
        System.out.println("Displaying text: " + text);
    }

    // 方法重载:参数顺序不同
    public void display(String text, int number) {
        System.out.println("Displaying text " + text + " and number " + number);
    }

    public void display(int number, String text) {
        System.out.println("Displaying number " + number + " and text " + text);
    }

    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.display(10);
        example.display(10, 20);
        example.display(10.5);
        example.display("Hello");
        example.display("World", 100);
        example.display(200, "Java");
    }
}

面相对象特征--封装

1)封装的概念

封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问

2)怎么封装

Java中有四种访问修饰符,分别是public、private、protected和default(即不写任何修饰符),它们控制类、方法和字段的访问级别。

Java中可以封装属性(变量),封装方法

3)封装的好处

  1. 隐藏类的信息
  2. 方便加入控制语句
  3. 通过特定的方法访问
  4. 方便修改实现

封装属性(变量)

public class MyClass {
    private int value1;
    private String value2;

    public int getValue1() {
        return value1;
    }
    public void setValue1(int value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        //设置数据
        myClass.setValue1(1);
        myClass.setValue2("1");
        //拿去数据
        System.out.println(myClass.getValue1());
        System.out.println(myClass.getValue2());
    }
}

封装方法

public class Calculator {
    public int add(int num1, int num2) {
        return num1 + num2;
    }
    
    private int subtract(int num1, int num2) {
        return num1 - num2;
    }
    
    protected int multiply(int num1, int num2) {
        return num1 * num2;
    }
}

面相对象特征--继承

1)基本定义

  • 子类:继承了一个父类的类称为子类。子类可以访问和使用父类中的非私有成员变量和方法。
  • 父类:被继承的类称为父类或者基类

理解:继承就是子类可以使用父类中的部分(权限足够--->访问权限修饰符)成员变量和成员方法等

下图:猫类和狗类就可以使用动物类中的成员变量和成员方法等

 

2)什么时候需要继承

个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么,多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成继承关系

何时使用继承

符合is-a关系的设计,可以使用继承

例如:

     猫是动物

     狗是动物

这样我们就可以使猫和狗继承动物类

3)语法演示

继承的语法通过 extends关键字,可以声明一个类B继承另外一个类A,定义格式如下:

[修饰符] class 类A {

              ...

}

[修饰符] class 类B extends 类A {

                     ...

}

类B,称为子类/派生类

类A,称为父类/基类

代码演示:

本代码中提到的super()语法下文会有解释

// 父类
class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + " is eating.");
    }
}

// 子类继承父类
class Dog extends Animal {
    private String breed;

    public Dog(String name, String breed) {
        super(name); // 调用父类的构造函数
        this.breed = breed;
    }

    public void bark() {
        System.out.println(name + " is barking.");
    }
}

public class InheritanceExample {
    public static void main(String[] args) {
        Dog myDog = new Dog("Buddy", "Golden Retriever");
        myDog.eat(); // 继承父类的方法
        myDog.bark(); // 子类特有的方法
    }
}

 4)继承的好处

 继承的好处

  1. 继承的出现减少了代码冗余,提高了代码的复用性
  2. 继承的出现,更有利于功能的扩展
  3. 继承的出现让类与类之间产生了is-a的关系,为多态的使用提供了前提

5)继承注意或继承细则

  1. 子类会继承父类所有的实例变量和实例方法
  2. 子类不能直接访问父类中私有的(private)的成员变量和方法
  3. 在Java 中,继承的关键字用的是“extends”,表示子类是对父类的扩展
  4. Java支持多层继承(继承体系)
  5. 一个父类可以同时拥有多个子类
  6. Java只支持单继承,不支持多重继承

Object最大的父类

类 java.lang.Object,是类层次结构的根类,即所有其它类的父类。每个类都使用 Object作为超类

当一个类没有显示的继承其他类时,默认继承Object类

方法的重写 

1)定义

     当父类方法功能无法实现子类的需求时,可以在子类中对方法进行重写

    子类可以对从父类中继承来的方法进行改造,我在程序执行时,子类的方法将覆盖父类的方法,人们称为方法的重写也称为方法的覆盖

理解:动物类中有一个方法为动物吃饭,但是狗类继承动物类需要狗吃骨头,那么父类方法无法实现子类所需求的功能,我们就就可以在子类中对父类的方法重写.

注意:构造方法,静态方法不能重写,成员变量不存在重写

2)方法重写的规则
  • 子类重写的方法必须和父类被重写的方法名称,参数列表相同
  • 子类重写的方法的返回值类型与父类保存一致
  • 子类重写的方法使用的访问权限不能小于父类被重写方法的访问权限
  • 注意:① 父类私有方法不能重写跨包的父类默认权限的方法也不能重写
  • 子类方法抛出的异常不能大于父类被重写方法的异常
// 定义一个父类
class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

// 定义子类,继承自Animal
class Dog extends Animal {
    // 重写父类的sound方法
    @Override
    public void sound() {
        System.out.println("汪汪汪");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.sound(); // 输出: 动物发出声音

        Dog dog = new Dog();
        dog.sound(); // 输出: 汪汪汪
    }
}

上面代码,我们可以在重写方法前面看到@Override

3)@Override使用说明

@Override是java中定义的注解标签,用来进行标记(进阶部分细讲) 写在方法上面,表示此方法是从父类重写而来,用来检测是不是满足重写方法的要求. 这个注解就算不写,只要格式满足要求,也是正确的方法覆盖重写.建议保留,这样编译器可以帮助我们检查格式,另外也可以让阅读源代码的程序员清晰的知道这 是一个重写的方法

面相对象特征--多态

1)定义

父类引用指向子类对象,从而产生多种形态

Animal dog = new Dog();

Animal cat = new Cat();

同一种事物,在不同时刻表现不同状态

二者存在直接或者间接的继承关系时,父类引用指向子类的对象,即形成多态

2)向上转型

class Animal{
   void eat(){ 
   
    }
}
class Cat extends Animal{
 void eat() {
   System.out.println("狗吃骨头");
  }
}


Animal x=new Cat() //向上造型,Cat对象提升到Animal对象
x.eat() //在编译奇迹只能调用父类中定义的方法, 如果子类重写了父类方法,那么运行时
调用子类重写的方法

3)多态环境下对成员方法的调用

class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // 多态,父类引用指向子类对象
        Animal animal2 = new Cat(); // 多态,父类引用指向另一个子类对象

        animal1.makeSound(); // 输出 "Dog barks",调用了Dog类中的重写方法
        animal2.makeSound(); // 输出 "Cat meows",调用了Cat类中的重写方法
    }
}

简单的说:编译看左边,运行看右边。

4)多态环境下对静态成员方法的调用

class Animal {
    public static void staticMethod() {
        System.out.println("Animal's static method");
    }
    
    public void instanceMethod() {
        System.out.println("Animal's instance method");
    }
}

class Dog extends Animal {
    public static void staticMethod() {
        System.out.println("Dog's static method");
    }
    
    @Override
    public void instanceMethod() {
        System.out.println("Dog's instance method");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        
        animal1.staticMethod(); // 输出 "Animal's static method"
        animal1.instanceMethod(); // 输出 "Dog's instance method"
        
        Dog.staticMethod(); // 输出 "Dog's static method"
    }
}

静态方法不能被重写,Dog类中只是写了一个和Animal类中一样的静态方法

简单的说:编译和运行都看左边

5)多态环境下对成员变量的调用

class Animal {
    String name = "Animal";

    public void printName() {
        System.out.println("Animal's name: " + name);
    }
}

class Dog extends Animal {
    String name = "Dog";

    @Override
    public void printName() {
        System.out.println("Dog's name: " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        
        animal1.printName(); // 输出 "Dog's name: Dog"
        System.out.println(animal1.name); // 输出 "Animal"
    }
}

简单的说:编译和运行都看等号左边。

注意:变量不存在被子类覆写这一说法,只有方法存在覆写

6)向下转型

class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("Dog barks");
    }

    void fetch() {
        System.out.println("Dog fetches the ball");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 向上转型

        animal.makeSound(); // 输出 "Dog barks"
        
        // 下面这行代码会导致编译时错误:Animal 类型没有 fetch 方法
        // animal.fetch();

        // 需要向下转型才能调用 fetch 方法
            Dog dog = (Dog) animal; // 向下转型
            dog.fetch(); // 输出 "Dog fetches the ball"
    }
}

向下转型的作用是:为了使用子类中的特有方法。

多态性的好处:提高代码的扩展性

接口​​​​​​​

1)什么是接口

1.生活中的接口

接口:一个组件插在一个接口上,从而实现功能.例如:U盘

2.java中的接口

我们将一个组件写成接口,然后我们可以将这个组件插在不同的类上.

可以使用Java接口来实现 

 2)面向接口编程

从本质上讲,接口是一种特殊的抽象类,这种抽象类中包含抽象方法

3)认识接口 

3)定义

接口的定义:使用 interface 关键字用来声明一个接口

4)语法

[访问修饰符] interface 接口名称 [extends 其他的接口名1,….其他的接口名n] {

                 // 声明常量 抽象方法 静态方法 默认方法

  }

5)接口的使用

类使用implements关键字实现接口。在类声明中,Implements 关键字放在class声明后面

[访问修饰符] class 类名 implements 接口名1,接口名2……{}(可以同时承接多个接口)

结合继承:

[访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{}

6)接口的特性

  1. 接口是隐式抽象的,主要用来定义功能.
  2. 接口中可以定义静态常量,抽象方法,静态方法,默认方法.
  3. 一个接口能继承其它多个接口.
  4. 接口不能实例化对象.
  5. 接口是要被类实现,一个接口可以被多个实现
  6. 当类实现接口的时候,类要实现接口中所有的抽象方法,否则,该类必须 声明为抽象的类.
  7. 接口与实现类之间存在多态性

关键字

1)this关键字

this关键字代表当前对象(this永远指向的是当前地址对象中的元素)

用法:使用this关键字引用成员变量

           使用this关键字引用成员方法或构成方法

在一个类的方法或构造方法内部,可以使用“this.成员变量名”这样的格式来引用成员变量名,常常用来区分同名的成员变量和局部变量​​​​​​​

public class Demo{
   int name;
 public Demo(int name){
       this.name = name;
  }
}

2)super关键字

可以在子类中调用父类的成员

 注意 

super和this的用法相同,this表示当前对象,但是super表示父类中成员,而不是父类的对象

尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员

super的追溯不仅限于直接父类还可以是父类的父类

super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

误区:  不要把super误认为是父类对象,在创建子类对象时,不会创建父类对象.

           只会将父类中的信息加载到子类对象中存储

在创建子类对象时,必须在子类构造方法的第一行调用父类的构造方法

在子类的构造方法中不写都是默认的======>  这里的调用   super();

3)static关键字

概念

static修饰的变量称作为类变量

static被称为静态,可以用来修饰类的成员变量,成员方法,代码块,内部类

static修饰,静态属性在内存只有一份,所有对象共享。(个人理解:static修饰变量在类中就变成一个固定值。========> 直接改变了初始模板

特点:          

  1. 静态的变量随着类的加载而加载,类加载好了 ,静态变量就可以使用
  2. 优先与对象存在
  3. 修饰的成员,被所有对象所共享
  4. 可不创建对象直接使用类名调用

static属性   

静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中只有一个。    

特点

  1. 静态成员变量也称为类变量,在内存中只有一份,所有对象可以共享
  2. 一般情况将类中所有属性相同就会定义为静态
  3. 静态变量可以在任意方法、代码块、构造器中直接使用。
  4. 可以通过类名.静态变量直接访问,也可以通过对象静态变量的方式访问(但是更推荐使用类名.静态变量的方式)
     public class Chinese{

             String name ;//姓名

             static String country=”中国”;//国家

             }

static可以修饰成员方法,修饰的成员方法也称为类方法,可以直接通过类名访问

  一旦使用了非静态的成员变量 那么此方法就不能定义为静态的方法

  静态的方法中只能使用静态的成员变量

  非静态的方法可以使用静态的成员变量

 因为不需要实例就可以访问static方法,因此static方法内部不能有this, 也不能有super

 

静态成员变量与非静态成员变量的区别

   个人理解:

  1. 静态变量在内存中只有一份,所有的共用一份。这样也节约空间
  2. 静态变量可以直接调用,不用创建相应的类对象
  3. 静态变量可以在非静态方法或者静态方法中使用
  4. 非静态变量不可以在静态方法中使用
  5. 静态变量一般具有一定性(所有物体所对应的这个变量都相同)

final关键字

  1. final修饰类,方法,参数,成员变量(常量)
  2. final 修饰的类是不能被继承的,所以不能修饰抽象类例如java中String类,就是由final修饰的
  3. final修饰的方法不能被重写
  4. final修饰方法的参数 参数值在方法中不能被改变的
  5. final修饰的成员变量值不能改变,因此称为常量

在类定义时,值就确定,直接赋值,赋值后值不能改变,所以建议使用static修饰final

例如:final static int  a = 10;

在定义类时,值不确定必须在创建对象后,在构造方法对其进行赋值,每个对象中拥有一个常量final int  count;

作者建议:学习知识在于深度理解,多动手、多动脑,总能更快地领悟。不要仅仅停留在阅读代码的层面,亲自动手敲打一遍,会带来更丰富的收获。通过实践,我们能够更深入地理解知识,掌握技能,并且在解决问题时更加得心应手。相信自己的能力,坚持不懈地实践,你将会取得更大的进步和成就。让学习成为一种习惯,让动手实践成为你提升的捷径,加油!你是最棒的!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/755719.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MambaMixer:突破Transformers限制的高效深度学习架构

深度学习模型尤其是Transformers架构,已经在诸如自然语言处理、计算机视觉和时间序列预测等多个领域取得了显著成就。然而,随着模型输入序列长度的增加,传统的Transformers模型面临着显著的扩展性问题。其核心问题在于,Transforme…

GPT-5:编织未来智能的经纬

GPT-5技术突破预测 随着GPT-5的预告,人工智能的叙事正步入一个崭新的篇章。想象中的GPT-5不仅是自然语言处理(NLP)领域的革命,更是对“理解”本身的一次重新定义。它可能集成深度学习的最新进展,如自注意力机制的进一步…

Java访问修饰符的区别

public:公开的,任何地方都可以访问。 protected:受保护的,同一个包中的类和所有子类(可跨包)可以访问。 private:私有的,只有在同一个类中可以访问。 默认(无修饰符):包级…

SmartEDA革新来袭:融合Multisim与Proteus精髓,引领电子设计新纪元!

在电子设计领域,每一次技术的革新都如同春风化雨,滋润着设计师们的心田。今天,我们迎来了一个划时代的电子设计自动化(EDA)工具——SmartEDA,它不仅融合了业界知名的Multisim和Proteus的精华,更…

【计算机毕业设计】077停车场微信小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

FreeRTOS移植到STM32

一、找一个STM32的裸机工程模板 我们以STM32F103裸机程序为例 随便找的一个裸机程序 二、去官网上下载FreeRTOS V9.0.0 源码 在移植之前,我们首先要获取到 FreeRTOS 的官方的源码包。这里我们提供两个下载 链 接 , 一 个 是 官 网 : http:…

若依 ruoyi 分离版 vue 简单的行内编辑实现

需要实现的效果&#xff1a;双击文本 - 修改文本 - 保存修改。 原码&#xff1a;仅文本显示文字内容 <el-table-column label"商品" align"center" prop"goodsName" width"200" v-if"columns[1].visible" /> 实现…

基于Vue,mysql,JavaEE的简单投票与投票管理系统

项目介绍 ​ 本项目&#xff0c;基于Vue2.6,mysql,JavaEE 实现简单的投票与投票管理系统 项目地址 VotingSystem: 投票系统1.0 管理员和普通用户 (gitee.com) 有问题请评论私聊哦 项目分类 数据库 创建投票人&#xff0c;被投票人&#xff0c;投票关系&#xff08;追踪谁…

基于Java的蛋糕预定系统【附源码+LW】

摘 要 当今社会进入了科技进步、经济社会快速发展的新时代。国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统购物方式采取了人工的管理方法&#xff0c;但这种管理方法存…

使用 nvm 管理 Node 版本及 pnpm 安装

文章目录 GithubWindows 环境Mac/Linux 使用脚本进行安装或更新Mac/Linux 环境变量nvm 常用命令npm 常用命令npm 安装 pnpmNode 历史版本 Github https://github.com/nvm-sh/nvm Windows 环境 https://nvm.uihtm.com/nvm.html Mac/Linux 使用脚本进行安装或更新 curl -o- …

阿里云服务器数据库迁云: 数据从传统到云端的安全之旅(WordPress个人博客实战教学)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一、 开始实战1.2创建实验资源1.3重置云服务器ECS的登录密码&#xff08;请记住密码&#xff09;1.4 设置安全组端口1…

武汉星起航:跨境热销新趋势,亚马逊美国站与欧洲站选品大赏

亚马逊作为全球领先的电商平台&#xff0c;其美国站和欧洲站一直是全球卖家争相入驻的热门站点。这两个站点不仅拥有庞大的消费群体和完善的物流体系&#xff0c;更以其独特的选品策略吸引了众多消费者的目光。武汉星起航将深入剖析亚马逊美国站和欧洲站当前热销的选品&#xf…

【Qt】之【Bug】大量出现“未定义的标识符”问题

背景 构建时出现大量错误 原因 中文注释问题 解决 方法1. 报错代码附近的中文注释全部删掉。。。 方法2. 报错的文件添加 // Chinese word comment solution #pragma execution_character_set("utf-8")

爱奇艺 Opal 机器学习平台:特征中心建设实践

01 综述 Opal 是爱奇艺大数据团队研发的一站式机器学习平台&#xff0c;旨在提升特征迭代、模型训练效率&#xff0c;帮助业务提高收益。整个平台覆盖了机器学习生命周期中特征生产、样本构建、模型探索、模型训练、模型部署等在内的多个关键环节。其中特征作为模型训练的基石…

ZYNQ MPSOC浅说

1 MPSOC PL端 Zynq UltraScale MPSoC PL 部分等价于 FPGA。简化的 FPGA 基本结构由 6 部分组成&#xff0c;分别为可编程输入/输出单元、基本可编程逻辑单元、嵌入式块RAM、丰富的布线资源、底层嵌入功能单元和内嵌专用硬核等。 2 MPSOC PS端 MPSoC 实际上是一个以处理器为…

Quartz定时任务组件

官网&#xff1a;http://www.quartz-scheduler.org/ 1&#xff09;job - 任务 - 你要做什么事&#xff1f; 2&#xff09;Trigger - 触发器 - 做什么事&#xff0c;什么时候触发&#xff0c;可以传入任务 3&#xff09;Scheduler - 任务调度 - 可以传入多个触发器进行任务调…

软件测试之接口测试(Postman/Jmeter)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是接口测试 通常做的接口测试指的是系统对外的接口&#xff0c;比如你需要从别的系统来…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-29残差网络ResNet

29残差网络ResNet import torch from torch import nn from torch.nn import functional as F import liliPytorch as lp import matplotlib.pyplot as plt# 定义一个继承自nn.Module的残差块类 class Residual(nn.Module):def __init__(self, input_channels, num_chan…

AI副业赚钱攻略:掌握数字时代的机会

前言 最近国产大模型纷纷上线&#xff0c;飞入寻常百姓家。AI副业正成为许多人寻找额外收入的途径。无论您是想提高家庭收入还是寻求职业发展&#xff0c;这里有一个变现&#xff0c;帮助您掌握AI兼职副业的机会。 1. 了解AI的基础知识 在开始之前&#xff0c;了解AI的基础…

【笔记】Spring Cloud Gateway 实现 gRPC 代理

Spring Cloud Gateway 在 3.1.x 版本中增加了针对 gRPC 的网关代理功能支持,本片文章描述一下如何实现相关支持.本文主要基于 Spring Cloud Gateway 的 官方文档 进行一个实践练习。有兴趣的可以翻看官方文档。 由于 Grpc 是基于 HTTP2 协议进行传输的&#xff0c;因此 Srping …