1、面向对象程序设计的概念
(1)类(Class):类是Java中的基本构建块,用于定义对象的属性和行为。它是创建对象的模板或蓝图。
(2)对象(Object):对象是类的实例。每个对象都具有自己的状态(属性)和行为(方法),可以通过调用对象的方法来访问和修改其状态。
(3)封装(Encapsulation):封装是将相关的数据和方法组合在类中,并对外部隐藏对象内部的实现细节。通过封装,可以保护对象的数据不被直接访问和更改,只能通过公共接口进行操作。
(4)继承(Inheritance):继承是指一个类从另一个类派生出新的类,称为子类或派生类,继承了父类或基类的属性和方法。继承可以实现代码的重用和层次化组织。
(5)多态(Polymorphism):多态是指对象可以根据上下文的不同表现出多种形态。通过多态,可以使用统一的接口来处理不同类型的对象,提高代码的灵活性和可扩展性。
(6) 抽象(Abstraction):抽象是指从类的实例中提取出通用的特征和行为,形成抽象类或接口。抽象类只能被继承而不能实例化,接口定义了一组方法的规范,需要具体类来实现。
(7)重写(Override):重写是指在子类中重新定义父类中已有的方法,使其适应子类的特定需求。子类可以根据需要修改、扩展或覆盖继承自父类的方法。
(8)接口(Interface):接口定义了一组方法的声明,而不包含实现。通过实现接口,类可以表达它们具备某种功能或遵循某种协议。
这些概念共同构成了Java面向对象程序设计的基础。通过合理地运用这些概念,可以实现代码的模块化、可复用性和可维护性,并更好地设计和组织程序结构。
2、类的定义
public class ClassName {
//成员变量(属性)
private dataType variable1;
private dataType variable2;
//构造方法
public ClassName(dataType variable1, dataType variable2){
this.variable1 = variable1;
this.variable2 = variable2;
}
//成员方法
public void method1(){
//方法逻辑
}
public dataType method2(){
//方法逻辑
return result;
//可选:getter和setter方法用于访问和修改私有成员变量public dataType getVariable1(){
return variable1;
}
public void setVariable1(dataType variable1){
this.variable1 = variable1;
}
//可选:toString方法用于返回对象的字符串表示形式@0verride
public String toString() {
return "ClassName{variable1 = variable1,variable2 = variable2}";
}
}
(1)类名:使用class关键字后跟类名来定义类。
(2)成员变量:定义类的属性,可以是任何数据类型。通常使用private访问修饰符来限制对成员变量的直接访问,并提供公共的getter和setter方法来访问和修改私有成员变量。
(3)构造方法:构造方法用于创建对象时进行初始化操作,其名称与类名相同。可以定义多个构造方法,通过不同的参数列表来区分。
(4)成员方法:定义类的行为和功能,可以包含任何合法的Java代码。成员方法可以对类的属性进行操作,并可选择返回值或不返回值。
(5)可选方法: getter和setter方法用于访问和修改私有成员变量;toString()方法用于返回对象的字符串表示形式,常用于调试和打印输出。
注意,在Java中一个源文件通常只能包含一个public类,且类名应与文件名一致。
通过创建类的实例,即对象,可以使用类中定义的属性和方法来完成具体的操作和任务。
ClassName object = new ClassName(value1,value2);
object.method1();
dataType result = object.method2();
System.out.println(object.getVariable1());
3、对象及引用
在Java中,对象是类的实例化。当通过关键字`new`创建一个对象时,实际上就在内存中分配了一块空间用于存储该对象的属性和方法。
引用是指对象的地址或指针。在Java中,变量可以声明为某个类的类型,这样的变量实际上持有的是对象的引用而不是对象本身。通过引用,我们可以访问和操作对象的属性和方法。
(1)对象是通过使用new关键字来创建的,语法如下:
```java
ClassName object = new ClassName();
```
(2)引用是用于指向对象的变量,它保存的是对象在内存中的地址。例如:
```java
ClassName object = new ClassName(); // 创建对象并将其引用赋给object
```
(3)可以使用引用来访问对象的属性和调用对象的方法。例如:
```java
object.property; // 访问对象的属性
object.method(); // 调用对象的方法
```
(4)多个引用可以指向同一个对象。例如:
```java
ClassName object1 = new ClassName();
ClassName object2 = object1; // object2引用和object1指向相同的对象
```
(5) 当一个对象没有任何引用指向时,它会变成垃圾(garbage),Java的垃圾回收机制会自动回收这些无引用的对象所占用的内存空间。
(6)引用变量可以为null,表示没有指向任何对象。例如:
```java
ClassName object = null; // object引用为空,没有指向任何对象
```
在Java中,使用对象和引用的概念可以方便地管理和操作数据。通过创建对象并使用引用来操作对象,我们可以实现面向对象编程的特性,如封装、继承和多态等。
4、继承与多态
在Java中,继承(Inheritance)和多态(Polymorphism)是面向对象编程的重要特性。
(1)继承:
1)继承是指一个类可以从另一个类派生出子类或派生类,继承了父类或基类的属性和方法。
2)子类可以继承父类的非私有成员变量和方法,并且可以通过关键字`super`调用父类的构造方法和方法。
3)继承提供了代码的重用性,可以通过在子类中添加新的行为或修改已有行为来满足特定的需求。
(2)多态:
1. 多态是指一个对象具有多个形态或表现方式的特性。
2. 多态实现了同一个方法可以根据不同的对象表现出不同的行为。
3. 多态通过向上转型(Upcasting)来实现,即将子类对象赋值给父类引用变量。
下面是一个简单示例来说明继承和多态的概念:
```java
class Animal {
public void sound() {
System.out.println("动物发出声音");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("猫发出喵喵的声音");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("狗发出汪汪的声音");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Cat();
Animal animal2 = new Dog();
animal1.sound(); // 输出:猫发出喵喵的声音
animal2.sound(); // 输出:狗发出汪汪的声音
}
}
```
在上述示例中,Animal是一个基类,Cat和Dog是它的子类。通过继承,子类继承了父类的sound()方法,并可以对其进行重写(Override)以实现自己的特定行为。
在main方法中,我们使用父类类型的引用变量来指向子类的对象。这就是多态的体现,即将不同类型的子类对象赋值给父类引用。调用animal1.sound()和animal2.sound()时,虽然是通过相同的方法名调用,但由于存在多态性,结果会根据具体对象的类型而有所不同。
通过继承和多态机制,可以实现更灵活、可扩展和可维护的代码结构,提高代码的重用性和可读性。
5、抽象与接口
在Java中,抽象(Abstraction)和接口(Interface)是面向对象编程的重要概念,用于实现代码的模块化和扩展性。
(1)抽象:
1)抽象是从类的实例中提取出通用的特征和行为,形成抽象类或抽象方法。
2)抽象类是一个不能实例化的类,只能被继承。它可以包含抽象方法、具体方法和成员变量。
3)抽象方法是没有实际实现的方法,只有声明。子类必须实现所有父类中的抽象方法。
(2)接口:
1)接口定义了一组方法的规范,但不包含实现。它是一种纯抽象的类,所有的方法都是抽象方法,所有的属性都是常量。
2)类可以通过实现接口来表达它们具备某种功能或遵循某种协议,一个类可以实现多个接口。
3)实现接口要求类必须实现接口中定义的所有方法,以满足接口的约定。
(3)抽象类和接口的区别:
1)抽象类可以包含成员变量和具体方法的实现,而接口只能包含常量和抽象方法。
2)一个类只能继承一个抽象类,而可以实现多个接口。
3)抽象类的目的是为了提供一种通用的基类,而接口的目的是为了定义方法的规范和实现类之间的契约。
//抽象类
abstract class Animal{
protected String name;
public Animal(String name){
this.name = name;
}
//抽象方法
public abstract void sound();
//具体方法
public void move(){
System.out. println(name+"在移动");
}
}
//实现接口
interface Swimmer {
void swim();
}
class Dog extends Animal implements Swimmer {
public Dog(String name){
super(name);
}
@Override
public void sound(){
System.out.println(name + "发出汪汪的声音");
}
@Override
public void swim(){
System.out.println(name + "在游泳");
}
}
public class Main {
public static void main(String[] args){
Dog dog = new Dog("小狗");
dog.sound(); //输出:小狗发出汪汪的声音
dog.swim(); //输出:小狗在游泳
dog.move(); //输出:小狗在移动
}
}
在上述示例中,Animal是一个抽象类,它包含了一个抽象方法 sound()和一个具体方法 move()。 Swimmer是一个接口,其中定义了一个抽象方法 swim()。Dog 类继承自Animal类,并实现了Swimmer接口。通过继承和实现接口,Dog 类既继承了抽象类的特性,又遵循了接口的规范。
抽象类和接口可以帮助我们在设计和组织代码时达到更高的抽象层次,提高代码的可扩展性和灵活性。
抽象类用于表示一种通用的概念,而接口用于定义方法的规范和实现类之间的契约。
6、内部类与匿名类
在Java中,内部类(Inner Class)和匿名类(Anonymous Class)是用于实现更灵活和模块化的代码结构的特性。
(1)内部类:
1)内部类是定义在其他类内部的类。
2)内部类可以访问外部类的成员变量和方法,包括私有成员。
3)内部类可以分为静态内部类、成员内部类、局部内部类和匿名内部类等几种类型。
class OuterClass {
private int outerData;
//成员内部类
class InnerClass {
public void printOuterData() {
System.out.println("Outer data:" + outerData);
}
}
public void outerMethod(){
//局部内部类
class LocalInnerClass {
public void printMessage(){
System.out.println("Hello from local inner class");
}
}
LocalInnerClass localInner = new LocalInnerClass();
localInner.printMessage();
}
}
public class Main {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
//创建内部类对象
OuterClass.InnerClass inner = outer.new InnerClass();
inner.printOuterData();
//调用外部类方法,创建局部内部类对象
outer.outerMethod();
}
}
在上述示例中,outerClass 定义了一个成员内部类InnerClass和一个方法 outerMethod()内部定义了一个局部内部类
LocalInnerClass。通过创建外部类对象来创建内部类对象,可以访问外部类的成员变量和方法。
(2)匿名类
1)匿名类是没有明确命名的内部类,它用于创建一个单独的对象并覆盖某个方法。
2)匿名类通常用于实现接口或继承抽象类,并在创建对象时直接定义其行为。
3)匿名类只能使用一次,无法在其他地方再次引用。
interface Greeting {
void sayHello();
}
public class Main {
public static void main(String[] args) {
//创建匿名类对象并实现接口方法
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello from anonymous class");
}
};
greeting.sayHello();//输出:Hello from anonymous class
}
}
在上述示例中,通过创建一个实现了Greeting接口的匿名类对象,直接在对象创建时定义了sayHello()方法的实现。内部类和匿名类提供了更灵活的方式来组织和设计代码,可以在需要的地方直接定义并使用类。内部类可以访问外部类的成员,并提供了更好的封装性和代码复用性。匿名类则适合用于简单的实现接口或继承抽象类的场景,减少了不必要的类定义和代码编写。
7、自动装箱拆箱
在Java中,自动装箱(Autoboxing)和拆箱(Unboxing)是指基本数据类型与对应的包装类之间的自动转换。装箱、拆箱
(1)自动装箱(Autoboxing):将基本数据类型自动转换为对应的包装类对象。例如,将int类型的数据赋值给Integer类型的变量。
示例:
```java
int num = 10;
Integer integerObj = num; // 自动装箱
```
(2)自动拆箱(Unboxing):将包装类对象自动转换为对应的基本数据类型。例如,将Integer类型的对象赋值给int类型的变量。
示例:
```java
Integer integerObj = 20;
int num = integerObj; // 自动拆箱
```
自动装箱和拆箱使得在需要使用包装类对象或者基本数据类型的地方可以自由进行转换,从而提供了更便捷的编程体验。编译器会在适当的时候自动插入装箱或拆箱的代码,简化了代码编写过程。