Java程序设计复习提纲(中:面向对象)

目录

上:Java程序设计复习提纲(上:入门语法) - 孤飞 - 博客园 (cnblogs.com)

  • 基本语法与编译运行

  • 数据类型和关键字

  • 常用语法

  • 数组与字符串

  • 异常处理


中:本文

  • 面向对象和类

下:Java程序设计复习提纲(下:图形界面) - 孤飞 - 博客园 (cnblogs.com)

  • 图形界面

面向对象概述

面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用“对象”来设计软件和实现复杂的软件系统。在OOP中,每个对象都是一个特定类(class)或类型(type)的实例,类定义了对象的数据和可以对这些数据执行的操作。

下面是面向对象编程的一些主要概念:

  1. 类(Class):类是对象的蓝图或模板。一个类定义了创建对象时其数据的类型和可用的方法。

  2. 对象(Object):对象是类的实例。每个对象都有其自己的状态和行为。状态由属性(也称为字段或变量)表示,行为由方法(也称为函数)表示。

  3. 继承(Inheritance):继承是一种机制,可以创建一个新类(子类)来继承一个已存在的类(父类)的属性和方法。子类可以添加新的属性和方法,也可以重写父类的方法。

  4. 封装(Encapsulation):封装是将对象的状态(属性)和行为(方法)打包在一起,并隐藏对象内部的实现细节。通过封装,可以保护对象的内部状态不被外部直接访问,只能通过对象提供的方法来访问。

  5. 多态(Polymorphism):多态是指允许一个接口被多种实际类型实现。在OOP中,多态允许我们以统一的方式处理不同类型的对象,只要它们都实现了相同的方法或接口。

如果你学过Python,那么你应该已经接触过面向对象编程,因为Python也是一种支持OOP的语言。例如,你可能已经定义过自己的类,创建过对象,或者使用过继承。下面是一个简单的Python类的例子:

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print("Woof, my name is " + self.name)

fido = Dog("Fido")
fido.bark()  # prints "Woof, my name is Fido"

在这个例子中,Dog是一个类,它有一个属性name和一个方法bark。然后我们创建了一个Dog的实例fido,并调用了它的bark方法。

在Java中,面向对象编程的概念和使用方法与Python类似。以下是一个Java版本的同样的狗狗类:

public class Dog {
    private String name;

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

    public void bark() {
        System.out.println("Woof, my name is " + this.name);
    }

    public static void main(String[] args) {
        Dog fido = new Dog("Fido");
        fido.bark();  // prints "Woof, my name is Fido"
    }
}

在这个Java版本的例子中,Dog仍然是一个类,它有一个私有属性name和一个公有方法bark。然后我们在main方法中创建了一个Dog的实例fido,并调用了它的bark方法。

你可以看到,虽然两种语言的语法不同,但是面向对象编程的主要概念在两种语言中都是相同的。

类的概念

类(Class)是Java中的核心概念,它是面向对象编程的基础。以下是关于Java类的一些主要知识点:

  1. 基本概念:在Java中,类是一个模板,定义了一类对象的属性(也称为字段或成员变量)和方法(也称为函数或成员函数)。对象是类的实例,代表了类的一个特定实例。

  2. 定义一个类:在Java中,定义一个类的基本语法如下:

    public class MyClass {
        // fields (variables)
        private int myField;
    
        // methods
        public void myMethod() {
            // method body
        }
    }
    

    这定义了一个名为MyClass的类,包含一个私有字段myField和一个公共方法myMethod

  3. 对象的创建:使用new关键字和构造函数可以创建类的新实例。例如:MyClass obj = new MyClass();会创建一个MyClass的新对象,并将其赋值给obj

  4. 构造函数:构造函数是一种特殊的方法,用于初始化新创建的对象。构造函数的名称必须与类名相同,且没有返回类型。如果未在类中明确定义构造函数,Java会提供一个默认的无参数构造函数。

  5. this关键字:在类的方法中,this关键字用于引用调用当前方法的对象。它常常用在构造函数和设置器(setter)方法中,以区分成员变量和参数。

  6. static关键字static关键字可以用于定义类级别的变量和方法。静态变量(也称为类变量)在所有对象之间共享,静态方法(也称为类方法)可以在没有对象的情况下直接通过类名调用。

对象的构造和初始化

在Java中,对象的创建和初始化涉及到以下几个关键的概念:

  1. 对象的创建:在Java中,使用new关键字和构造器(constructor)来创建一个新的对象。例如,new Dog("Fido")会创建一个新的Dog对象。

  2. 构造方法:构造方法是一种特殊类型的方法,用于创建和初始化对象。构造方法的名称必须与类名相同,且没有返回值(也不用声明void)。构造方法可以接受参数,这些参数用于初始化新创建的对象。例如:

    public class Dog {
        private String name;
    
        // This is a constructor
        public Dog(String name) {
            this.name = name;
        }
    }
    

    在这个例子中,Dog类的构造方法接受一个name参数,用于初始化Dog对象的name属性。

  3. this引用:在Java中,this是一个特殊的变量,它引用的是当前对象。在构造方法或其他实例方法中,你可以使用this来引用当前对象的属性或方法。例如,在上面的Dog类的构造方法中,this.name = name表示将构造方法的参数name赋值给当前对象的name属性。

  4. 初始化块:Java中还有一种特殊的“初始化块”(也称为“实例初始化块”),它在创建对象时运行,但是在构造方法之前。初始化块在每次创建对象时都会执行,而且它能访问所有的字段和方法,包括private。例如:

    public class Dog {
        private String name;
    
        // This is an initializer block
        {
            name = "Unknown";
        }
    
        // This is a constructor
        public Dog(String name) {
            this.name = name;
        }
    }
    

    在这个例子中,初始化块会在每次创建Dog对象时执行,并将name属性设置为"Unknown"。然后构造方法会运行,并可能将name属性更改为其他值。

  5. 默认构造方法:默认构造方法是Java类在没有定义任何构造方法时,编译器自动为其提供的一个无参数的构造方法。默认构造方法的主要任务是创建类的一个新实例。

    如果你在一个类中没有显式地定义任何构造方法,那么Java编译器会为你提供一个默认的构造方法。这个默认的构造方法没有参数,也没有任何执行语句。

    以下是一个例子:

    public class Dog {
        // No constructor is defined here
    }
    

    在这个例子中,我们并没有为Dog类定义任何构造方法,所以Java编译器会自动为我们提供一个默认的构造方法。这个默认的构造方法等同于以下的无参数构造方法:

    public class Dog {
        public Dog() {
            // No initialization code
        }
    }
    

    但是,一旦你为一个类定义了至少一个构造方法(不管这个构造方法是否有参数),那么Java编译器就不再提供默认的构造方法。在这种情况下,如果你还想拥有一个无参数的构造方法,你需要显式地定义它。

以上是Java对象构造和初始化的基本概念和用法。理解这些概念对于编写Java程序是非常重要的。

继承

在Java中,子类和继承是面向对象编程的核心概念。以下是这些概念的一些基本点:

  1. 继承:在Java中,一个类可以从另一个类继承字段和方法。这个被继承的类被称为父类或超类,继承它的类被称为子类。继承用关键字extends来表示。例如:

    public class Animal {
        public void eat() {
            System.out.println("The animal eats");
        }
    }
    
    public class Dog extends Animal {
        // Dog class inherits from Animal class
    }
    

    在这个例子中,Dog类是Animal类的子类,它继承了Animal类的eat方法。

  2. 方法重写:子类可以重写继承自父类的方法,以提供不同的实现。方法重写是多态的一种表现形式。例如:

    public class Dog extends Animal {
        @Override
        public void eat() {
            System.out.println("The dog eats");
        }
    }
    

    在这个例子中,Dog类重写了Animal类的eat方法,提供了不同的实现。

  3. super关键字:子类可以使用super关键字来引用父类的字段和方法。这在子类需要访问父类的实现时非常有用。例如,子类可以使用super关键字来调用父类的构造方法。例如:

    public class Animal {
        public Animal() {
            System.out.println("An animal has been created");
        }
    }
    
    public class Dog extends Animal {
        public Dog() {
            super();  // Call the constructor of the superclass (Animal)
            System.out.println("A dog has been created");
        }
    }
    

    在这个例子中,Dog类的构造方法调用了Animal类的构造方法。

  4. 公有方法读取:在Java中,子类不能直接访问父类的私有字段和方法。这是由Java的访问控制机制决定的,私有成员(字段或方法)仅在其所在的类内部可见。

    然而,子类可以通过继承的公有或保护方法访问和修改父类的私有字段,或者调用父类的私有方法。这些公有或保护方法被视为父类的公有接口或者是受保护的接口,子类可以通过这些接口与父类的私有成员进行交互。这样做的好处是封装性和数据隐藏,使得类的内部实现可以独立于外部接口进行改变,而不影响到使用该类的代码。

    以下是一个例子:

    public class Animal {
        private String name;
    
        public Animal(String name) {
            this.name = name;
        }
    
        // Public getter for the private field
        public String getName() {
            return this.name;
        }
    
        // Public setter for the private field
        public void setName(String name) {
            this.name = name;
        }
    }
    
    public class Dog extends Animal {
        public Dog(String name) {
            super(name);
        }
    
        public void printName() {
            // Accessing the private field of the superclass through a public method
            System.out.println("The dog's name is " + getName());
        }
    }
    

    在这个例子中,Dog类不能直接访问Animal类的私有字段name,但是它可以通过Animal类的公有方法getNamesetName来获取和修改name字段的值。

方法重写

Java中的方法重写(也称为方法覆盖)是子类提供父类已有方法的不同实现的机制。这是多态性的一个重要方面。以下是关于方法重写的一些关键点:

  1. 基本概念:当子类需要改变父类方法的行为时,子类可以提供与父类方法具有相同名称和参数的方法。这种行为称为方法重写。例如:

    public class Animal {
        public void makeSound() {
            System.out.println("The animal makes a sound");
        }
    }
    
    public class Dog extends Animal {
        @Override
        public void makeSound() {
            System.out.println("The dog barks");
        }
    }
    

    在这个例子中,Dog类重写了Animal类的makeSound方法。

  2. @Override 注解:你可以使用@Override注解来明确表示一个方法是重写的方法。这不仅可以提高代码的可读性,还可以让编译器帮你检查是否正确地重写了方法。如果没有正确地重写方法(例如,方法签名不同),编译器会报错。

  3. 方法签名:为了正确地重写一个方法,子类的方法必须具有与父类方法相同的名称和参数。返回类型应该相同,或者是父类方法返回类型的子类型。此外,子类方法的访问级别不能比父类方法的访问级别更严格。

  4. super关键字:在重写的方法中,你可以使用super关键字来调用父类的原始方法。例如:

    public class Dog extends Animal {
        @Override
        public void makeSound() {
            super.makeSound();  // Call the original method in the superclass
            System.out.println("In addition, the dog barks");
        }
    }
    

    在这个例子中,Dog类的makeSound方法首先调用了Animal类的makeSound方法,然后再打印出额外的信息。

  5. 重写与重载的区别方法重写方法重载是Java中两种非常重要的概念,它们都涉及到方法的使用,但是用法和意义有很大的区别。

    (1). 方法重写(Override):方法重写发生在父类和子类之间,当子类需要改变从父类继承的方法的行为时,可以提供一个与父类方法具有相同名称和参数的新方法。重写的方法必须有相同的名称、参数列表和兼容的返回类型,并且访问级别不能比父类方法的访问级别更严格。

    (2). 方法重载(Overload):方法重载发生在同一个类中,当类需要多个功能类似但参数不同的方法时,可以使用相同的方法名,但参数列表必须不同(即参数的类型、顺序或数量不同)。返回类型和访问修饰符可以不同。例如:

    public class MyClass {
        public void myMethod(int x) { ... }
    
        public void myMethod(String s) { ... }
    
        public void myMethod(int x, String s) { ... }
    }
    

    在这个例子中,myMethod方法被重载了三次,每次都有不同的参数列表。

    构造方法也可以被重载,以便为创建类的新实例提供不同的初始化选项。例如:

    public class MyClass {
        public MyClass() { ... }
    
        public MyClass(int x) { ... }
    
        public MyClass(int x, String s) { ... }
    }
    

    在这个例子中,MyClass的构造方法被重载了三次,每次都有不同的参数列表,提供了不同的初始化选项。

    然而,构造方法不能被重写。在Java中,构造方法是与类名相同的特殊方法,它用于初始化新创建的对象。由于子类不能继承父类的构造方法,所以也就不存在重写构造方法的情况。

多态

多态性是面向对象编程的三大核心特性之一(封装、继承和多态)。在Java中,多态性主要体现在接口和继承上。

以下是关于Java多态的一些关键知识点:

  1. 基本概念:多态性是指同一个接口可以有多种实现形式。在Java中,这通常意味着一个父类(或接口)引用可以指向一个子类对象。这个父类引用可以调用在父类中定义的任何方法,如果这些方法在子类中被重写,那么将会执行子类的版本。

  2. 动态方法分派:多态的核心在于动态方法分派,这是Java运行时系统的一部分。当一个方法被调用时,Java运行时系统查看对象的类型,然后运行与该类型关联的方法版本。例如:

    Animal myPet = new Dog();
    myPet.makeSound();  // Calls Dog's version of makeSound
    

    在这个例子中,尽管myPet的编译时类型是Animal,但是它的运行时类型是Dog,所以当我们调用myPet.makeSound()时,实际上调用的是Dog类的makeSound方法。

  3. 向上转型和向下转型:在Java中,你可以将一个子类对象赋值给一个父类引用,这被称为向上转型(upcasting),这是完全安全的。然而,你也可以将一个父类引用转型为子类引用,这被称为向下转型(downcasting),但这可能是不安全的,因为如果实际的对象类型并不是你期望的子类类型,那么会发生ClassCastException。例如:

    Animal myPet = new Dog();  // Upcasting
    Dog myDog = (Dog) myPet;  // Downcasting
    
  4. 抽象类和接口:在Java中,你可以使用抽象类和接口来定义通用的行为,并通过继承抽象类或实现接口来创建具有特定行为的类。抽象类和接口都可以用来实现多态性。

以上就是Java多态的基本概念和用法。理解这些概念对于掌握Java编程非常重要。

封装

封装是面向对象编程的三大核心特性之一(封装、继承和多态)。在Java中,封装主要体现在类和访问控制上。

以下是关于Java封装的一些关键知识点:

  1. 基本概念:封装是一种隐藏类的内部实现细节,只暴露出安全的操作和属性的机制。封装的主要目的是增加安全性和简化编程。

  2. 类和对象:在Java中,类是封装数据(属性)和行为(方法)的主要工具。对象是类的实例,代表了类的一个特定实例。

  3. 访问修饰符:Java提供了四种访问修饰符(private、protected、public和默认(包私有))来控制类成员的可见性。通过正确地使用访问修饰符,可以隐藏类的内部状态,并控制外部代码如何与对象交互。

    • private:只有类本身可以访问。
    • protected:类本身、同一包内的其他类和所有子类可以访问。
    • public:任何类都可以访问。
    • 默认(包私有):类本身和同一包内的其他类可以访问。
  4. getters和setters:在Java中,通常会使用getters(访问器)和setters(修改器)来访问和修改私有变量。这些方法允许你控制如何访问和修改这些变量,例如,你可以在setter中添加验证逻辑。

接口和抽象类是Java中重要的结构,它们都可以用于定义类的行为但不能实例化。

接口与抽象类

接口

  1. 基本概念:接口是一种定义一组方法(但不实现)的方式,它只包含常量和抽象方法的声明。接口提供了一种机制,使得类可以遵循特定的协议。

  2. 定义接口:使用interface关键字定义接口。接口的所有方法默认都是publicabstract的,所以这些关键字是可选的。例如:

    public interface MyInterface {
        void myMethod();
    }
    
  3. 实现接口:类可以使用implements关键字来实现接口,必须提供接口中声明的所有方法的实现。例如:

    public class MyClass implements MyInterface {
        public void myMethod() {
            // implementation
        }
    }
    
  4. 扩展接口:接口可以使用extends关键字扩展其他接口。

在Java中,接口主要用于定义一个行为规范,它定义了一组需要被实现的方法。接口可以被类实现(使用implements关键字),也可以被其他接口继承(使用extends关键字)。实现接口的类需要提供接口中所有方法的具体实现。

以下是一个使用接口的例子。假设我们正在编写一个程序,需要处理各种类型的动物。我们可以定义一个Animal接口,该接口声明了所有动物都应该有的行为:

public interface Animal {
    void eat();
    void move();
}

然后我们可以创建具体的动物类(如DogBird),并实现Animal接口:

public class Dog implements Animal {
    public void eat() {
        System.out.println("The dog eats dog food.");
    }

    public void move() {
        System.out.println("The dog runs.");
    }
}

public class Bird implements Animal {
    public void eat() {
        System.out.println("The bird eats bird food.");
    }

    public void move() {
        System.out.println("The bird flies.");
    }
}

在这个例子中,DogBird类都实现了Animal接口,所以它们都需要提供eatmove方法的具体实现。这就保证了我们可以在程序中统一处理所有类型的动物,因为我们知道所有的动物都有eatmove这两个行为。

例如,我们可以写一个方法,该方法接受一个Animal对象,调用它的eatmove方法:

public void doAnimalThings(Animal animal) {
    animal.eat();
    animal.move();
}

然后我们可以使用这个方法来处理任何类型的动物,无论是Dog还是Bird

Dog myDog = new Dog();
Bird myBird = new Bird();

doAnimalThings(myDog);  // Prints: "The dog eats dog food." and "The dog runs."
doAnimalThings(myBird); // Prints: "The bird eats bird food." and "The bird flies."

这就是接口的一个基本用法:它定义了一种契约,所有实现该接口的类都必须遵守这个契约。这使得我们可以编写更灵活和更通用的代码。

抽象类

  1. 基本概念:抽象类是一种不能实例化的类,它可以包含抽象方法(没有实现)和非抽象方法(有实现)。

  2. 定义抽象类:使用abstract关键字定义抽象类。例如:

    public abstract class MyAbstractClass {
        public abstract void myAbstractMethod();  // abstract method
    
        public void myConcreteMethod() {
            // implementation
        }
    }
    
  3. 扩展抽象类:类可以使用extends关键字来扩展抽象类,必须提供抽象类中所有抽象方法的实现。

接口、抽象类、普通类的区别

接口、抽象类和普通类是Java中三种不同类型的类结构。它们的主要区别如下:

  1. 接口(Interface):所有方法都是抽象方法

    • 接口是一种完全抽象的类型,只能包含公共的抽象方法(默认)和公共静态常量。
    • 一个类可以实现多个接口。
    • 从Java 8开始,接口可以包含默认方法和静态方法。
    • 接口不能包含构造方法。
    • 接口不能被实例化。
  2. 抽象类(Abstract Class):含有抽象方法和普通方法

    • 抽象类是一种部分抽象的类型,可以包含抽象方法和非抽象方法,以及变量。
    • 一个类只能继承一个抽象类。
    • 抽象类可以包含构造方法。
    • 抽象类不能被实例化,但可以被子类继承,子类必须实现抽象类中的所有抽象方法。
  3. 普通类(Class):没有抽象方法

    • 普通类(也称为具体类)是一种完全具体的类型,所有的方法都必须有具体的实现。
    • 一个类只能继承一个普通类。
    • 普通类可以包含构造方法。
    • 普通类可以被实例化。

总的来说,接口是为了实现多继承,定义共享的公共接口;抽象类是为了封装子类的公共行为,并且提供一些默认行为的实现;而普通类则是为了实现具体的功能。

内部类与匿名类

Java 中的内部类和匿名类是两种不同的类类型。以下是关于内部类和匿名类的基本知识:

内部类

内部类(Inner Classes)是定义在另一个类中的类。它们可以访问外部类的所有变量和方法,即使它们被声明为私有的。内部类的主要作用是帮助使代码更加整洁和可读,因为它们可以将相关的类组织在一起。

内部类分为两种类型:非静态内部类(也称为成员内部类)和静态内部类。

class OuterClass {
    class InnerClass {
        // This is a non-static inner class
    }

    static class StaticInnerClass {
        // This is a static inner class
    }
}

匿名类

匿名类(Anonymous Classes)是一种没有名字的内部类。它们主要用于需要仅使用一次的类,通常用在GUI事件处理或者在需要传递一个对象到某个方法,而该对象不会再被其他地方使用的情况下。

匿名类通常在你需要使用一个接口或者抽象类,但又觉得创建一个新的类太过冗余时使用。在创建匿名类的时候,你实际上是在声明并且实例化一个类的同时。

new InterfaceName() {
    // methods
}

或者

new AbstractClassName() {
    // methods
}

例如,以下代码创建了一个实现了 Runnable 接口的匿名类的实例:

new Thread(new Runnable() {
    public void run() {
        System.out.println("Running in a new thread.");
    }
}).start();

在这个例子中,我们创建了一个实现了 Runnable 接口的匿名类,并且立即使用它作为参数创建了一个新的 Thread 对象。匿名类的 run 方法被实现以打印一条消息,当新的线程启动时,这个消息就会被打印出来。

总的来说,内部类和匿名类都是为了提高代码的整洁性和可读性,使得更容易组织和管理相关的类和接口。

posted @ 2023-05-19 15:01  孤飞  阅读(62)  评论(0编辑  收藏  举报