-
什么是类与对象?
- 类(Class)是面向对象编程的基本概念之一,它是对具有相似属性和行为的对象进行抽象的模板。类定义了对象的共同特征和行为,类中包含属性(成员变量)和方法(成员函数)。
- 对象(Object)是类的实例化,是具体的实体,通过类创建而来。对象具有类所定义的属性和行为,可以与其他对象交互。
-
类的成员:
- 属性(成员变量):类中的属性用于描述对象的状态,它们是类的数据成员。属性可以是各种数据类型,如整数、浮点数、字符串等。
- 方法(成员函数):类中的方法用于定义对象的行为,它们是类的函数成员。方法可以访问和操作对象的属性,并实现类的功能。
package lyjm0626; import java.security.PublicKey; public class Book { //对象是事物存在的实体,可将对象分为两个部分:静态部分和动态部分,静态部分即属性,任何事物都具备自身属性,动态部分即事物具备行为 //类是具有相同特性和行为的一类事物的统称,是事物的抽象称呼 //类是封装对象的属性和行为的载体 String name; String author; String genres; int pages; String press; int publishedtime; public static void main(String[] args){ Book book1 = new Book(); book1.name="Java从入门到精通"; book1.author="明日科技"; book1.genres="教程书"; book1.pages=532; book1.press="清华大学出版社"; book1.publishedtime=2019; book1.showInfo(); } public void showInfo(){ System.out.println ("------信息显示-----"); System.out.println ("书名为" + name); System.out.println ("作者是" + author); System.out.println ("书本类型" + genres); System.out.println ("总页数为" + pages); System.out.println ("出版社为" + press); System.out.println ("出版时间为" + publishedtime); System.out.println ("------------------"); } }
-
类的封装与访问控制:
- 封装是OOP的一个重要特性,它将数据和方法封装在类的内部,隐藏内部实现细节,只暴露必要的接口给外部使用。
1: 内部属性和方法的使用 受到权限限制,不会被随意调用 保护的作用2: 通过 set 方法可以对属性进行检查,保证属性的合法性3: 通过 get 方法可以在返回属性数据时,做合法的格式化输出4: 读写分离 不直接操作变量5: 代码结构更加规范
- 访问控制修饰符(public、private、protected等)用于限制成员的访问权限,保护数据的安全性。
- 封装是OOP的一个重要特性,它将数据和方法封装在类的内部,隐藏内部实现细节,只暴露必要的接口给外部使用。
-
类之间的关系:
- 继承(Inheritance):通过继承,一个类可以派生出子类,子类继承了父类的属性和方法,并可以扩展或重写父类的功能。
-
父类与子类:继承关系通常是在类的层次结构中存在的,一个类可以成为另一个类的父类,而另一个类则成为子类。
-
属性和方法继承:子类继承了父类的属性和方法,子类可以使用父类的属性和方法,而无需重新编写相同的代码。
-
子类的扩展:子类可以在继承的基础上,添加新的属性和方法,以实现更具体的功能需求。子类也可以重写父类的方法,实现特定的行为。
-
继承的限制:继承并不是无限制的,父类的私有属性和方法在子类中是不可见的,子类只能继承父类的公有和受保护的属性和方法。
-
多层继承:在继承关系中,可以存在多层继承,即子类也可以成为其他类的父类,形成继承链。
-
Java中的继承:在Java编程语言中,使用关键字"extends"来建立继承关系,一个类可以继承另一个类的属性和方法。
class Animal { String name; void eat() { System.out.println(name + "正在吃东西"); } } class Dog extends Animal { void bark() { System.out.println(name + "正在汪汪叫"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.name = "旺财"; dog.eat(); // 输出:旺财正在吃东西 dog.bark(); // 输出:旺财正在汪汪叫 } } /*Animal类是父类,Dog类是Animal的子类。Dog类继承了Animal类的属性name和方法eat,并在此基础上添加了自己的方法bark。当创建Dog类的对象并调用方法时,可以看到Dog类成功继承了Animal类的功能,并实现了自己的扩展。这就是继承的基本概念和用法。*/
-
- 多态(Polymorphism):多态允许不同的类共享相同的接口或父类,并实现各自独特的行为,提高代码的灵活性和可扩展性。
-
继承与多态:多态通常与继承相结合。子类继承父类的方法,并可以在子类中重新定义这些方法,使得同一方法名可以在不同的子类中实现不同的功能。
-
同一接口:多态性要求不同的类实现相同的方法名和参数列表,即它们共享相同的接口。这样,可以通过父类或接口类型来引用不同的子类对象。
-
编译时绑定与运行时绑定:多态性实现了动态绑定(Dynamic Binding),也称为后期绑定。在编译时,编译器不确定实际调用的是哪个子类的方法,而在运行时才确定调用哪个子类的方法。
-
方法的重写:多态性需要子类重写父类的方法,即子类的重写方法与父类的被重写方法有相同的方法签名。
-
多态的实现:多态性可以通过继承和接口实现。在Java等面向对象编程语言中,通过继承实现多态,也可以通过接口实现多态。
class Animal { void makeSound() { System.out.println("动物发出叫声"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("狗发出汪汪叫声"); } } class Cat extends Animal { @Override void makeSound() { System.out.println("猫发出喵喵叫声"); } } public class Main { public static void main(String[] args) { Animal animal1 = new Dog(); Animal animal2 = new Cat(); animal1.makeSound(); // 输出:狗发出汪汪叫声 animal2.makeSound(); // 输出:猫发出喵喵叫声 } }
-
- 继承(Inheritance):通过继承,一个类可以派生出子类,子类继承了父类的属性和方法,并可以扩展或重写父类的功能。
-
对象的创建与使用:
- 创建对象:通过类的构造函数(Constructor)来创建对象,构造函数初始化对象的属性和状态。
- 对象的操作:通过对象调用类中定义的方法,实现对对象的操作和功能调用。
-
方法重写:面向对象编程中的一种重要概念,也称为覆盖或覆写。它发生在子类(派生类)继承了父类(基类)的时候。当子类继承了父类的方法后,可以对父类的方法进行重新定义,以适应子类的需求。
-
继承关系:方法重写必须在子类和父类之间存在继承关系。子类是父类的扩展,因此子类继承了父类的方法。
-
方法签名:方法重写要求子类的重写方法与父类的被重写方法有相同的方法签名。方法签名包括方法的名称、参数个数、参数类型和返回类型。
-
@Override注解:在Java等一些编程语言中,可以使用@Override注解来标识方法是重写的,这样可以提高代码的可读性和可维护性。
-
动态绑定:方法重写实现了多态性,即在运行时动态绑定方法的调用。当通过子类的对象调用重写的方法时,实际调用的是子类中的方法而不是父类的方法。
-
class Animal {
void makeSound() {
System.out.println("动物发出叫声");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("狗发出汪汪叫声");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("猫发出喵喵叫声");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.makeSound(); // 输出:狗发出汪汪叫声
animal2.makeSound(); // 输出:猫发出喵喵叫声
}
}
/*Animal类是父类,Dog和Cat类是Animal的子类。
子类Dog和Cat分别重写了父类Animal中的makeSound方法。
当通过子类对象调用makeSound方法时,实际调用的是子类中重写的方法,而不是父类的方法。
这就是方法重写的实现。*/
7. 类型转型
向上转型(Upcasting):
- 向上转型是从子类转换为父类的过程。在向上转型中,子类的对象可以被当作其父类的对象来使用,即子类对象可以赋值给父类的引用类型。
- 向上转型是安全的,因为子类继承了父类的属性和方法,可以保证在父类引用中只使用子类对象共有的方法。
- 向上转型在编译时进行,编译器会将子类对象看作父类对象,因此只能调用父类的方法。
- 向上转型实现了多态性,通过父类引用指向不同的子类对象,实现了统一的接口来处理不同的子类对象。
class Animal { void makeSound() { System.out.println("动物发出叫声"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("狗发出汪汪叫声"); } } public class Main { public static void main(String[] args) { // 向上转型,子类对象赋值给父类引用 Animal animal = new Dog(); // 调用的是子类的重写方法 animal.makeSound(); // 输出:狗发出汪汪叫声 } }
向下转型(Downcasting):不安全的 ,必须是先向上转型之后才能向下转型
- 向下转型是从父类转换为子类的过程。在向下转型中,父类引用可以被转换为子类引用,从而可以调用子类独有的方法。
- 向下转型是有风险的,因为并非所有的父类引用都指向子类对象。如果尝试将一个不正确的类型转换为子类引用,会导致运行时异常(ClassCastException)。
- 为了安全地进行向下转型,通常需要使用instanceof运算符来检查对象的类型是否与所需类型相匹配。
class Animal { void makeSound() { System.out.println("动物发出叫声"); } } class Dog extends Animal { @Override void makeSound() { System.out.println("狗发出汪汪叫声"); } void fetch() { System.out.println("狗正在接飞盘"); } } public class Main { public static void main(String[] args) { Animal animal = new Dog(); // 向下转型,将父类引用转换为子类引用 if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.fetch(); // 输出:狗正在接飞盘 } else { System.out.println("该动物不是狗"); } } }