java面向对象程序设计---下

java面向对象程序设计—下

封装

封装是将一个类的实现细节隐藏起来,只暴露必要的接口给外部使用的过程。

类的封装

class student {
	
	int age;
	String name;
	double score;
	
	void introduce(){ 	//方法 = 函数
								  //不需要传参,因为Java面向对象,可以直接访问它里面的成员变量
		System.out.println("name=" +name + "age="+age + "score="+score);
	}
	
	void testFunc(){
		System.out.println("testFunc");
	}
}


public class Test {
	public static void main(String[] args) {
		student stu1 = new student(); //实例化一个对象,类=模板,只有属性和方法,类不能直接使用需要先实例化一个对象
		//struct student *p;
		//p = malloc(sizeof(struct student));
		
		stu1.age = 18;
		stu1.name = "zheng";
		stu1.score = 100;
		stu1.introduce();//不需要传参,可以访问到同组变量
	}
}

修饰符

  1. private(私有):
    • 仅允许在声明了该成员的类中访问。
    • 其他类无法直接访问私有成员,即使是同一个包中的类也不行。
  2. protected(受保护):
    • 允许在声明了该成员的类、同一包中的类、以及该类的子类中访问。
    • 类外部的非子类不能直接访问 protected 成员。
  3. public(公有):
    • 可以被任意类访问,包括不同包中的类。
    • 公有成员对所有类可见,无论是否在同一包中,也无论是否是子类。
  4. 默认(包访问,没有显式修饰符):
    • 允许在声明了该成员的类和同一包中的类中访问。
    • 对于同一个包中的其他类而言,没有声明访问修饰符的成员具有包访问权限。
访问修饰符类内部同一包中的类子类不同包中的类
private
protected
public
默认

构造方法

定义

构造方法是Java类中的一种特殊类型的方法,其主要用途是在对象创建时对对象进行初始化。构造方法的名称必须与类名相同,并且没有返回类型,包括 void。当使用 new 关键字创建对象时,构造方法会被隐式调用,以确保对象在创建时处于一个合适的状态。

构造方法的特点

  1. 方法名与类名相同: 构造方法的名称必须与类名一致。
  2. 没有返回类型: 构造方法没有返回类型,甚至不需要声明 void
  3. 可以有参数: 构造方法可以接受参数,用于在对象创建时传递初始值。
  4. 可以有多个构造方法: 一个类可以有多个构造方法,称为构造方法的重载。这样可以提供不同的初始化方式。

构造方法的使用

public class Car {
    private String make;
    private String model;
    private int year;

    // 无参构造方法
    public Car() {
        make = "Unknown";
        model = "Unknown";
        year = 0;
    }

    // 有参构造方法
    public Car(String make, String model, int year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    // 其他方法
    public void displayInfo() {
        System.out.println("Car: " + year + " " + make + " " + model);
    }

    public static void main(String[] args) {
        // 使用无参构造方法创建对象
        Car car1 = new Car();
        car1.displayInfo();  // 输出:Car: 0 Unknown Unknown

        // 使用有参构造方法创建对象
        Car car2 = new Car("Toyota", "Camry", 2022);
        car2.displayInfo();  // 输出:Car: 2022 Toyota Camry
    }
}

构造方法的重载

构造方法的重载是指在同一个类中定义多个构造方法,这些构造方法具有相同的名称但参数列表不同的特征。通过构造方法的重载,可以为对象的创建提供不同的初始化方式。

// 无参构造方法
public Car() {
    this("Unknown", "Unknown", 0);   //无参构造方法的调用使用了 this() 关键字来调用有参构造方法,确保代码的复用。
}

// 有参构造方法
public Car(String make, String model, int year) {
    this.make = make;
    this.model = model;
    this.year = year;
}

继承

定义

在Java中,继承是面向对象编程的一项重要特性,它允许一个类(子类)基于另一个类(父类)来定义,从而实现代码的重用和扩展。继承通过使用 extends 关键字来实现。

定义继承关系: 使用 extends 关键字,子类继承父类。

访问父类成员: 子类可以访问父类的非私有成员(字段和方法),即使它们在不同的包中。

方法重写: 子类可以重写父类的方法,提供自己的实现。使用 @Override 注解可以帮助检查是否正确地重写了父类的方法。

super关键字: super 关键字用于调用父类的方法或访问父类的字段。在构造方法中,super() 可以用于调用父类的构造方法,确保父类的初始化工作得以执行。

构造方法调用: 子类的构造方法可以通过 super() 调用父类的构造方法,确保父类的初始化工作得以执行。

多态性: 子类对象可以被视为父类对象,这允许在父类类型的引用中持有子类对象,并且在运行时调用适当的方法。

**构造方法的调用顺序:**在创建子类对象时,构造方法的调用顺序是先调用父类的构造方法,然后再调用子类的构造方法。这确保了对象的初始化按照正确的顺序进行。

继承的使用

代码复用

通过继承,可以在不重新编写代码的情况下使用现有类的功能,从而提高代码的复用性。子类继承父类的属性和方法,可以在子类中专注于扩展或修改特定行为。

// 父类
public class Animal {
    public void eat() {
        System.out.println("动物正在吃东西");
    }
}

// 子类
public class Dog extends Animal {
    public void bark() {
        System.out.println("狗在叫");
    }
}

// 在其他类中使用
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.eat();  // 继承父类的方法
        myDog.bark(); // 子类的方法
    }
}

重写@Override

通过继承,可以创建一个基类,然后通过创建不同的子类来扩展或修改基类的功能。这种方式使得在应对变化时更加灵活,可以轻松地增加或修改类的行为。

// 父类
public class Shape {
    public void draw() {
        System.out.println("绘制形状");
    }
}

// 子类扩展
public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个圆");
    }
}

// 子类修改
public class Square extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个正方形");
    }
}

子类访问父类的成员

成员变量和成员方法的访问是基于就近原则的,这意味着如果子类中存在与父类相同名称的成员变量或成员方法,子类将优先使用自己的成员而不是父类的。

子类调用父类的构造方法

子类的构造方法可以使用 super 关键字调用父类的构造方法。这通常用于确保在创建子类对象时,首先执行父类的初始化工作。

当子类的构造方法中没有手动添加 super 关键字时,Java 编译器会自动调用父类的无参构造方法(如果存在的话)。这是因为每个类的构造方法的第一行,如果没有显式调用父类的构造方法(使用 super 关键字),则会默认调用父类的无参构造方法。

// 父类
public class Animal {
    public Animal() {
        System.out.println("父类无参构造");
    }
}

// 子类
public class Dog extends Animal {
    // 子类构造方法,没有手动添加super关键字
    public Dog() {
        System.out.println("子类无参构造");
    }

    public static void main(String[] args) {
        // 创建子类对象
        Dog myDog = new Dog();
    }
}

子类访问自己的构造方法

this():

多态

定义

​ 简单的说就是一个对象有多种形态,具体点说多态就是父类中的属性和方法被子类继承后,可以具有不同的数据类型或不同的行为,使父类中的同一个属性和方法在父类与各个子类具有不同的含义。

条件

继承:必须存在继承;
重写:子类必须对父类中的方法进行重写;
向上转型:通过父类的引用调用子类的重写的方法;

使用

class Animal{
    public String name;
    public int age;
    public void eat(){
        System.out.println(this.name + "吃饭");
    }
 
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
class Dog extends Animal{ //继承
@Override   //重写               
    public void eat() { //向上转型
        System.out.println(this.name + "吃狗粮");
    }
    public void sleep(){
        System.out.println(this.name + "在睡觉");
    }
 
    public Dog(String name, int age) {
        super(name, age);
    }
}
class Cat extends Animal{ //继承
    @Override   //重写 
    public void eat() { //向上转型
        System.out.println(this.name + "吃猫粮");
    }
    public void sleep(){
        System.out.println(this.name + "在睡觉");
    }
 
    public Cat(String name, int age) {
        super(name, age);
    }
}
public class Test1 {
    public static void eat(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("花花",1);
        Dog dog = new Dog("多多",2);
        eat(cat);
        eat(dog);
    }
}

向上转型向下转型

向上转型

向上转型是将子类的对象引用赋给父类类型的引用,这样的引用可以操作子类对象,但只能调用父类中定义的方法。这是安全的,因为子类对象肯定包含了父类对象的所有特性。

 Animal animal = new Dog(); // 向上转型

向下转型

向下转型是将父类类型的引用重新转换为子类类型的引用,以便调用子类中特有的方法。在进行向下转型之前,需要确保原始对象是可以被转型为目标类型的。

  Dog dog = (Dog) animal; // 向下转型

优缺点

优点

可扩展能力更强

缺点

属性没有多态性,当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性;
构造方法没有多态性;

final关键字

特点

修饰方法 不能重写父类的 final 方法

修饰变量 只能被赋值一次,而且一旦赋值后,就不能再修改

修饰类 阻止其他类继承该类,确保该类的实现不会被修改或者不希望有子类继承

抽象类

定义

抽象类是一种特殊的类,它不能被实例化,但可以被继承。抽象类通常用于提供一些共有的属性和方法,并定义一些抽象方法,这些抽象方法在具体的子类中必须被实现。

基本概念

定义抽象类 使用 abstract 关键字定义抽象类。抽象类可以包含抽象方法和具体方法。

继承抽象类 子类继承抽象类,并实现抽象类中的抽象方法。如果子类是抽象类,它可以选择性地实现抽象方法。

实例化抽象类 抽象类不能被实例化 可以通过向上转型的方式使用抽象类的引用指向其子类的对象

Animal myDog = new Dog(); // 向上转型
myDog.makeSound(); // 调用被子类实现的抽象方法
myDog.eat(); // 调用抽象类中的具体方法

抽象类中的构造方法 构造方法的主要作用是在创建子类对象时初始化抽象类的成员。

优点

强制子类实现抽象方法,确保了代码的一致性

提高代码重用,抽象类可以包含通用的属性和方法,这些代码可以被多个子类继承和共享

Java内部类

成员内部类

定义在一个类的内部,并且在类的成员位置。它可以访问外部类的所有成员,包括私有成员。

局部内部类

定义在一个方法或作用域内,只能在该方法或作用域内使用。

匿名内部类

没有显式地定义类的名称,通常用于实现接口或继承父类。

静态内部类

定义在类的内部,使用 static 关键字修饰,与外部类的实例无关,可以通过外部类直接访问。

异常

在Java中,异常是程序在执行期间发生的问题。Java异常处理机制用于捕获和处理这些问题,以确保程序不会因错误而崩溃。主要通过 try-catch 块来处理异常。

概念

顶级父类 Throwable,它有两个主要的子类:ExceptionError

try {
    // 可能抛出异常的代码
    int result = divide(10, 0);
    System.out.println("Result: " + result);
} catch (ArithmeticException e) {
    // 捕获并处理异常
    System.out.println("Error: " + e.getMessage());
} finally {
    // 无论是否发生异常,都会执行的代码块
    System.out.println("finally都会执行");
}

异常顺序

子类在前 父类在后

补充

finally

用于定义在无论是否发生异常都会执行的代码块。这种结构用于确保资源的释放或清理工作,无论是否发生异常,finally 中的代码都会被执行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值