目录
1.面向对象的基础概念
对象就是存在的具体实体,具有明确定义的状态和行为,是面向对象编程的核心,用来描述现实世界中的实体,为计算机应用程序提供实体基础,也是完成特定任务一个封装。这样描述对象却是有点罗嗦。因为与传统的C语言不通,C语言是过程语言,而java语言是面向对象的语言,所以对象是java语言的核心。
那到底什么是对象,能举个例子吗?其实在我们生活中,什么都可以抽象成为对象,比如你有一辆汽车,这辆车就是对象了,这个对象(汽车),它有颜色,牌子,有产地等等,这些我们也可以称为是它的属性,它也能开动,要维修等等这些操作,我们成为是它的行为。这就是对象了。
在面向对象编程中(简称:OOP),现实世界的所有事物全都被视为对象。OOP的目标是在计算机程序中,模拟现实世界中的概念,我们可以借助对象的描述就能够在计算机程序中用类似的实体模拟现实世界中的实体。同时OOP也是设计和实现软件系统的方法。
2.面向对象的四大特征
1-封装(Encapsulation):是一种将对象的数据(属性)和行为(方法)组合在一起,并隐藏内部状态和实现细节的机制。封装的主要目的是实现数据和操作的保护,确保对象的完整性和安全性。在Java怎么可以实现封装呢?主要有以下两个实现方法。
---将类的属性设置为 private
,以防止外部直接访问。
---提供 public
的 getter 和 setter 方法来访问和修改这些私有属性。
例:
public class Person {
// 私有属性,外部无法直接访问
private String name;
private int age;
// 构造方法,用于初始化对象状态
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 公共方法,允许读取私有属性name
public String getName() {
return name;
}
// 公共方法,允许修改私有属性name
public void setName(String name) {
this.name = name;
}
// 公共方法,允许读取私有属性age
public int getAge() {
return age;
}
// 公共方法,允许修改私有属性age
public void setAge(int age) {
if (age > 0) { // 可以添加逻辑来验证数据
this.age = age;
}
}
}
2-继承(Inheritance):继承是一种机制,允许一个类(子类)继承另一个类(父类或超类)的属性和方法。这使得子类可以重用父类的代码,并可以扩展或修改父类的行为。继承支持代码的复用,并有助于建立一个层次结构。
例子:
//创建父类Animal
public class Animal {
public String name;
public Animal(String name){
this.name = name;
}
public void eat(){
System.out.println(name+"is eating");
}
public void sleep(){
System.out.println(name+"is sleeping");
}
//一个通用方法,可以被子类重写以提供特定实现
public void makeSound(){
System.out.println(name+"makes a sound ");
}
}
//创建子类Dog,它继承来自父类Animal
public class Dog extends Animal{
public String breed;
public Dog(String name,String breed){
super(name);// 调用父类的构造方法
this.breed = breed;
}
//重写父类的makeSound方法
@Override
public void makeSound(){
System.out.println(name+"barks.");
}
//Dog类特有的方法
public void fetch(){
System.out.println(name+"is fetching the ball");
}
}
现在,我们可以创建 Dog 类的实例,并调用它的方法,包括从 Animal 类继承的方法和 Dog 类特有的方法。
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog("Buddy","Golden Retriever");
//调用继承自Animal类的方法
myDog.eat();
myDog.sleep();
myDog.makeSound();//调用重写后的makeSound方法
//调用Dog类特有的方法
myDog.fetch();
//打印Dog对象的属性
System.out.println("Dog's breed: "+myDog.breed);
}
}
3-多态(Polymorphism):多态是指允许不同类的对象对同一消息做出响应,但具体的行为会根据对象的实际类型而有所不同。多态可以通过方法重写(Override)和方法重载(Overload)实现。这使得代码更加灵活,能够处理不同类型的对象。
1-重写:
重写是运行时多态的一种表现,它指的是子类提供一个与父类中具有相同方法名、参数列表和返回类型的方法。子类的重写方法会覆盖父类中的方法。
重写的要点:
- 继承关系:只有在继承关系中,子类才能重写父类的方法。
- 方法签名:重写的方法必须具有与父类中被重写方法相同的方法名、参数列表和返回类型。
- 访问控制:子类重写的方法不能有比父类更严格的访问控制(例如,不能将父类的
protected
方法重写为private
)。 - 返回类型:子类重写的方法返回类型应该与父类方法一致或为更具体的类型(协变返回类型)。
例:
//创建一个父类Animal
public class Animal {
public void makeSound(){
System.out.println("Some sound");
}
}
//创建一个子类Dog继承自父类Animal
public class Dog extends Animal {
@Override
public void makeSound(){
System.out.println("Bark");
}
}
创建子类对象并向上转型
// Animal myAnimal = new Dog(); 这个语句创建了一个 Dog 类型的对象,并通过向上转型将其赋值给 // Animal 类型的引用 myAnimal。Dog 是 Animal 的子类,所以可以把它赋值给 Animal 类型的引用。
public class Main {
public static void main(String[] args) {
Animal a= new Dog();
a.makeSound();//输出”Bark“
}
}
2-重载:重载是编译时多态的一种表现,它指的是在一个类中可以有多个同名方法,但它们的参数列表不同(参数类型、数量或顺序不同)。
重载的要点:
- 方法名:重载的方法必须具有相同的方法名。
- 参数列表:重载的方法必须具有不同的参数列表(参数类型、数量或顺序)。
- 返回类型:虽然可以不同,但返回类型不是决定重载的关键因素(主要依据是参数列表)。
- 访问控制:重载的方法可以有不同的访问控制修饰符。
例:
//创建一个Calculator类,写三个参数不同但名字相同的add方法
public class Calculator {
public int add(int a,int b){
return a+b;
}
public double add(double a, double b){
return a+b;
}
public int add(int a,int b,int c){
return a+b+c;
}
}
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
System.out.println(calculator.add(5,10));
System.out.println(calculator.add(5.5,40.1));
System.out.println(calculator.add(5,10,42));
}
}
4-抽象(Abstraction):抽象是简化复杂系统的过程,通过提取关键特征并忽略不相关的细节来创建模型。在OOP中,抽象类和接口被用来定义不能被实例化的类,它们提供了一个框架,子类可以在此基础上进行扩展。
-
抽象类:
- 使用
abstract
关键字定义的类,称为抽象类。抽象类不能被实例化,但可以被继承。 - 抽象类可以包含抽象方法和具体方法。抽象方法没有实现,必须在子类中重写。
- 使用
-
接口:
- 接口是一种形式的抽象,它定义了一组方法规范,但不实现这些方法。
- 任何类都可以实现多个接口,必须提供接口中所有方法的具体实现。
抽象类
- 定义:使用
abstract
关键字定义。 - 目的:作为其他类的基类,提供一些基本实现,同时保留一些抽象方法供子类实现。
- 特点:
- 抽象类可以包含属性和方法。
- 抽象类可以有构造方法。
- 抽象类不能被实例化。
例:接口类
abstract class Animal{
public String name ;
public Animal(String name){
this.name = name;
}
public abstract void makeSound();//抽象方法
public void eat(){
System.out.println(name+"is eating");
}
}
class Dog extends Animal{
public Dog(String name){
super(name);
}
@Override
public void makeSound(){
System.out.println(name+"says Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog("Buddy");
animal.eat();
animal.makeSound();//输出”Buddy says Bark“
}
}
接口方法:
//首先,我们定义一个接口 Movable,它声明了一个方法 move,该方法将被实现接口的任何类所实现。
public interface Movable {
void move();
}
//接下来,我们创建一个类 Car,它实现了 Movable 接口,并提供了 move 方法的具体实现。
public class Car implements Movable{
private String brand;
public Car(String brand){
this.brand = brand;
}
//实现Movable 接口的move 方法
@Override
public void move(){
System.out.println(brand+"car is moving");
}
}
//最后,我们演示如何在 Main 类中使用 Car 类,它实现了 Movable 接口。
public class Main {
public static void main(String[] args) {
//创建car对象
Car car = new Car("Toyota");
//通过多态调用move方法
car.move();//输出“Toyota car is moving”
}
}