Java程序设计复习提纲(中:面向对象)
目录
上:Java程序设计复习提纲(上:入门语法) - 孤飞 - 博客园 (cnblogs.com)
-
基本语法与编译运行
-
数据类型和关键字
-
常用语法
-
数组与字符串
-
异常处理
中:本文
- 面向对象和类
下:Java程序设计复习提纲(下:图形界面) - 孤飞 - 博客园 (cnblogs.com)
- 图形界面
面向对象概述
面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用“对象”来设计软件和实现复杂的软件系统。在OOP中,每个对象都是一个特定类(class)或类型(type)的实例,类定义了对象的数据和可以对这些数据执行的操作。
下面是面向对象编程的一些主要概念:
-
类(Class):类是对象的蓝图或模板。一个类定义了创建对象时其数据的类型和可用的方法。
-
对象(Object):对象是类的实例。每个对象都有其自己的状态和行为。状态由属性(也称为字段或变量)表示,行为由方法(也称为函数)表示。
-
继承(Inheritance):继承是一种机制,可以创建一个新类(子类)来继承一个已存在的类(父类)的属性和方法。子类可以添加新的属性和方法,也可以重写父类的方法。
-
封装(Encapsulation):封装是将对象的状态(属性)和行为(方法)打包在一起,并隐藏对象内部的实现细节。通过封装,可以保护对象的内部状态不被外部直接访问,只能通过对象提供的方法来访问。
-
多态(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类的一些主要知识点:
-
基本概念:在Java中,类是一个模板,定义了一类对象的属性(也称为字段或成员变量)和方法(也称为函数或成员函数)。对象是类的实例,代表了类的一个特定实例。
-
定义一个类:在Java中,定义一个类的基本语法如下:
public class MyClass { // fields (variables) private int myField; // methods public void myMethod() { // method body } }
这定义了一个名为
MyClass
的类,包含一个私有字段myField
和一个公共方法myMethod
。 -
对象的创建:使用
new
关键字和构造函数可以创建类的新实例。例如:MyClass obj = new MyClass();
会创建一个MyClass
的新对象,并将其赋值给obj
。 -
构造函数:构造函数是一种特殊的方法,用于初始化新创建的对象。构造函数的名称必须与类名相同,且没有返回类型。如果未在类中明确定义构造函数,Java会提供一个默认的无参数构造函数。
-
this关键字:在类的方法中,
this
关键字用于引用调用当前方法的对象。它常常用在构造函数和设置器(setter)方法中,以区分成员变量和参数。 -
static关键字:
static
关键字可以用于定义类级别的变量和方法。静态变量(也称为类变量)在所有对象之间共享,静态方法(也称为类方法)可以在没有对象的情况下直接通过类名调用。
对象的构造和初始化
在Java中,对象的创建和初始化涉及到以下几个关键的概念:
-
对象的创建:在Java中,使用
new
关键字和构造器(constructor)来创建一个新的对象。例如,new Dog("Fido")
会创建一个新的Dog
对象。 -
构造方法:构造方法是一种特殊类型的方法,用于创建和初始化对象。构造方法的名称必须与类名相同,且没有返回值(也不用声明void)。构造方法可以接受参数,这些参数用于初始化新创建的对象。例如:
public class Dog { private String name; // This is a constructor public Dog(String name) { this.name = name; } }
在这个例子中,
Dog
类的构造方法接受一个name
参数,用于初始化Dog
对象的name
属性。 -
this引用:在Java中,
this
是一个特殊的变量,它引用的是当前对象。在构造方法或其他实例方法中,你可以使用this
来引用当前对象的属性或方法。例如,在上面的Dog
类的构造方法中,this.name = name
表示将构造方法的参数name
赋值给当前对象的name
属性。 -
初始化块: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
属性更改为其他值。 -
默认构造方法:默认构造方法是Java类在没有定义任何构造方法时,编译器自动为其提供的一个无参数的构造方法。默认构造方法的主要任务是创建类的一个新实例。
如果你在一个类中没有显式地定义任何构造方法,那么Java编译器会为你提供一个默认的构造方法。这个默认的构造方法没有参数,也没有任何执行语句。
以下是一个例子:
public class Dog { // No constructor is defined here }
在这个例子中,我们并没有为
Dog
类定义任何构造方法,所以Java编译器会自动为我们提供一个默认的构造方法。这个默认的构造方法等同于以下的无参数构造方法:public class Dog { public Dog() { // No initialization code } }
但是,一旦你为一个类定义了至少一个构造方法(不管这个构造方法是否有参数),那么Java编译器就不再提供默认的构造方法。在这种情况下,如果你还想拥有一个无参数的构造方法,你需要显式地定义它。
以上是Java对象构造和初始化的基本概念和用法。理解这些概念对于编写Java程序是非常重要的。
继承
在Java中,子类和继承是面向对象编程的核心概念。以下是这些概念的一些基本点:
-
继承:在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
方法。 -
方法重写:子类可以重写继承自父类的方法,以提供不同的实现。方法重写是多态的一种表现形式。例如:
public class Dog extends Animal { @Override public void eat() { System.out.println("The dog eats"); } }
在这个例子中,
Dog
类重写了Animal
类的eat
方法,提供了不同的实现。 -
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
类的构造方法。 -
公有方法读取:在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
类的公有方法getName
和setName
来获取和修改name
字段的值。
方法重写
Java中的方法重写(也称为方法覆盖)是子类提供父类已有方法的不同实现的机制。这是多态性的一个重要方面。以下是关于方法重写的一些关键点:
-
基本概念:当子类需要改变父类方法的行为时,子类可以提供与父类方法具有相同名称和参数的方法。这种行为称为方法重写。例如:
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
方法。 -
@Override 注解:你可以使用
@Override
注解来明确表示一个方法是重写的方法。这不仅可以提高代码的可读性,还可以让编译器帮你检查是否正确地重写了方法。如果没有正确地重写方法(例如,方法签名不同),编译器会报错。 -
方法签名:为了正确地重写一个方法,子类的方法必须具有与父类方法相同的名称和参数。返回类型应该相同,或者是父类方法返回类型的子类型。此外,子类方法的访问级别不能比父类方法的访问级别更严格。
-
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
方法,然后再打印出额外的信息。 -
重写与重载的区别:方法重写和方法重载是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多态的一些关键知识点:
-
基本概念:多态性是指同一个接口可以有多种实现形式。在Java中,这通常意味着一个父类(或接口)引用可以指向一个子类对象。这个父类引用可以调用在父类中定义的任何方法,如果这些方法在子类中被重写,那么将会执行子类的版本。
-
动态方法分派:多态的核心在于动态方法分派,这是Java运行时系统的一部分。当一个方法被调用时,Java运行时系统查看对象的类型,然后运行与该类型关联的方法版本。例如:
Animal myPet = new Dog(); myPet.makeSound(); // Calls Dog's version of makeSound
在这个例子中,尽管
myPet
的编译时类型是Animal
,但是它的运行时类型是Dog
,所以当我们调用myPet.makeSound()
时,实际上调用的是Dog
类的makeSound
方法。 -
向上转型和向下转型:在Java中,你可以将一个子类对象赋值给一个父类引用,这被称为向上转型(upcasting),这是完全安全的。然而,你也可以将一个父类引用转型为子类引用,这被称为向下转型(downcasting),但这可能是不安全的,因为如果实际的对象类型并不是你期望的子类类型,那么会发生
ClassCastException
。例如:Animal myPet = new Dog(); // Upcasting Dog myDog = (Dog) myPet; // Downcasting
-
抽象类和接口:在Java中,你可以使用抽象类和接口来定义通用的行为,并通过继承抽象类或实现接口来创建具有特定行为的类。抽象类和接口都可以用来实现多态性。
以上就是Java多态的基本概念和用法。理解这些概念对于掌握Java编程非常重要。
封装
封装是面向对象编程的三大核心特性之一(封装、继承和多态)。在Java中,封装主要体现在类和访问控制上。
以下是关于Java封装的一些关键知识点:
-
基本概念:封装是一种隐藏类的内部实现细节,只暴露出安全的操作和属性的机制。封装的主要目的是增加安全性和简化编程。
-
类和对象:在Java中,类是封装数据(属性)和行为(方法)的主要工具。对象是类的实例,代表了类的一个特定实例。
-
访问修饰符:Java提供了四种访问修饰符(private、protected、public和默认(包私有))来控制类成员的可见性。通过正确地使用访问修饰符,可以隐藏类的内部状态,并控制外部代码如何与对象交互。
- private:只有类本身可以访问。
- protected:类本身、同一包内的其他类和所有子类可以访问。
- public:任何类都可以访问。
- 默认(包私有):类本身和同一包内的其他类可以访问。
-
getters和setters:在Java中,通常会使用getters(访问器)和setters(修改器)来访问和修改私有变量。这些方法允许你控制如何访问和修改这些变量,例如,你可以在setter中添加验证逻辑。
接口和抽象类是Java中重要的结构,它们都可以用于定义类的行为但不能实例化。
接口与抽象类
接口
-
基本概念:接口是一种定义一组方法(但不实现)的方式,它只包含常量和抽象方法的声明。接口提供了一种机制,使得类可以遵循特定的协议。
-
定义接口:使用
interface
关键字定义接口。接口的所有方法默认都是public
和abstract
的,所以这些关键字是可选的。例如:public interface MyInterface { void myMethod(); }
-
实现接口:类可以使用
implements
关键字来实现接口,必须提供接口中声明的所有方法的实现。例如:public class MyClass implements MyInterface { public void myMethod() { // implementation } }
-
扩展接口:接口可以使用
extends
关键字扩展其他接口。
在Java中,接口主要用于定义一个行为规范,它定义了一组需要被实现的方法。接口可以被类实现(使用implements
关键字),也可以被其他接口继承(使用extends
关键字)。实现接口的类需要提供接口中所有方法的具体实现。
以下是一个使用接口的例子。假设我们正在编写一个程序,需要处理各种类型的动物。我们可以定义一个Animal
接口,该接口声明了所有动物都应该有的行为:
public interface Animal {
void eat();
void move();
}
然后我们可以创建具体的动物类(如Dog
和Bird
),并实现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.");
}
}
在这个例子中,Dog
和Bird
类都实现了Animal
接口,所以它们都需要提供eat
和move
方法的具体实现。这就保证了我们可以在程序中统一处理所有类型的动物,因为我们知道所有的动物都有eat
和move
这两个行为。
例如,我们可以写一个方法,该方法接受一个Animal
对象,调用它的eat
和move
方法:
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."
这就是接口的一个基本用法:它定义了一种契约,所有实现该接口的类都必须遵守这个契约。这使得我们可以编写更灵活和更通用的代码。
抽象类
-
基本概念:抽象类是一种不能实例化的类,它可以包含抽象方法(没有实现)和非抽象方法(有实现)。
-
定义抽象类:使用
abstract
关键字定义抽象类。例如:public abstract class MyAbstractClass { public abstract void myAbstractMethod(); // abstract method public void myConcreteMethod() { // implementation } }
-
扩展抽象类:类可以使用
extends
关键字来扩展抽象类,必须提供抽象类中所有抽象方法的实现。
接口、抽象类、普通类的区别
接口、抽象类和普通类是Java中三种不同类型的类结构。它们的主要区别如下:
-
接口(Interface):所有方法都是抽象方法
- 接口是一种完全抽象的类型,只能包含公共的抽象方法(默认)和公共静态常量。
- 一个类可以实现多个接口。
- 从Java 8开始,接口可以包含默认方法和静态方法。
- 接口不能包含构造方法。
- 接口不能被实例化。
-
抽象类(Abstract Class):含有抽象方法和普通方法
- 抽象类是一种部分抽象的类型,可以包含抽象方法和非抽象方法,以及变量。
- 一个类只能继承一个抽象类。
- 抽象类可以包含构造方法。
- 抽象类不能被实例化,但可以被子类继承,子类必须实现抽象类中的所有抽象方法。
-
普通类(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 方法被实现以打印一条消息,当新的线程启动时,这个消息就会被打印出来。
总的来说,内部类和匿名类都是为了提高代码的整洁性和可读性,使得更容易组织和管理相关的类和接口。
本文作者:孤飞
本文链接:https://www.cnblogs.com/ranxi169/p/17415155.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步