前言:
为什么要继承?
如:创建两个类,一个猫类,一个狗类,猫与狗都有眼睛,嘴巴,鼻子这些相同的属性,为了避免代码重复我们可以通过创建一个动物类,包含这些重复的属性,在通过继承的方式使用。
继承是面向对象编程中的重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用和扩展。通过继承,子类可以拥有父类的属性和方法,并且可以在此基础上添加新的属性和方法,实现代码的层次化和结构化。
下面通过一个简单的示例代码来演示继承的概念:
假设我们有一个父类 Animal,包含属性 name 和方法 eat(),表示动物的基本特征和行为。然后我们定义一个子类 Dog,继承自Animal类,并添加新的方法 bark(),表示狗特有的行为。
// Animal类 public class Animal { private String name; public Animal(String name) { this.name = name; } public void eat() { System.out.println(this.name + " is eating"); } } // Dog类继承自Animal类 public class Dog extends Animal { public Dog(String name) { super(name); // 调用父类的构造方法 } public void bark() { System.out.println(this.name + " is barking"); } public static void main(String[] args) { Dog dog = new Dog("Buddy"); dog.eat(); // 调用父类的eat方法 dog.bark(); // 调用子类的bark方法 } }
在上面的示例中,子类 Dog 继承自父类 Animal,通过关键字 extends 实现继承。子类 Dog 可以访问父类 Animal 的属性和方法,同时可以定义自己的属性和方法。在子类的构造方法中,使用 super(name) 调用父类的构造方法来初始化父类的属性。
继承的概念
继承是面向对象编程中的重要概念,它允许一个类(称为子类或派生类)获取另一个类(称为父类或基类)的属性和方法。通过继承,子类可以重用父类的代码,同时可以在不修改父类的情况下添加新的属性和方法,从而实现代码的重用和扩展。
在继承关系中,子类继承了父类的特征(属性)和行为(方法),并且可以在此基础上进行定制化。子类可以覆盖(重写)父类的方法,以实现自己特有的行为。继承还遵循了里氏替换原则,即子类可以替换父类出现的任何地方,而不会影响程序的正确性。
通过继承,可以建立类之间的层次关系,使得代码更加结构化和易于维护。同时,继承也有助于代码的扩展和灵活性,使得程序更容易适应需求变化。
继承的基本格式
在Java中,继承的基本格式如下所示:
class ParentClass { // 父类的属性和方法 } class ChildClass extends ParentClass { // 子类的属性和方法 }
在这个基本格式中:
- ParentClass 是父类,包含了一些属性和方法。
- ChildClass 是子类,通过关键字 extends 指定继承自哪个父类。
- 子类继承了父类的属性和方法,可以直接访问父类的公共和受保护成员。
- 子类可以重写父类的方法,实现多态性。
- 子类可以添加自己的属性和方法,扩展父类的功能。
继承的具体示例
以下是一个具体的Java代码示例,演示了继承的概念和用法
// 父类Animal class Animal { String name; public Animal(String name) { this.name = name; } public void eat() { System.out.println(name + " is eating"); } } // 子类Dog继承自Animal class Dog extends Animal { public Dog(String name) { super(name); } public void bark() { System.out.println(name + " is barking"); } } // 子类Cat继承自Animal class Cat extends Animal { public Cat(String name) { super(name); } public void meow() { System.out.println(name + " is meowing"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog("Buddy"); dog.eat(); // 调用父类方法 dog.bark(); // 调用子类方法 Cat cat = new Cat("Whiskers"); cat.eat(); // 调用父类方法 cat.meow(); // 调用子类方法 } }
在这个例子中,我们定义了一个父类
Animal
,包含name
属性和eat()
方法。然后分别定义了Dog
和Cat
两个子类,它们分别继承自Animal
类并添加了自己特有的方法bark()
和meow()
。在
Main
类的main
方法中,我们实例化了Dog
和Cat
对象,并调用它们的方法来展示继承的效果。通过这个具体的代码示例,可以更清晰地理解Java中继承的概念和用法。
super关键字
出现情况,子类和父类可能会存在相同名称的成员,在子类的方法中访问父类同名成员(作用)。
public class Base { int a; int b; public void methodA(){ System.out.println("Base中的methodA()"); } public void methodB(){ System.out.println("Base中的methodB()"); } } public class Derived extends Base{ int a; // 与父类中成员变量同名且类型相同 char b; // 与父类中成员变量同名但类型不同 // 与父类中methodA()构成重载 public void methodA(int a) { System.out.println("Derived中的method()方法"); } // 与基类中methodB()构成重写(即原型一致,重写后序详细介绍) public void methodB(){ System.out.println("Derived中的methodB()方法"); } public void methodC(){ // 对于同名的成员变量,直接访问时,访问的都是子类的 a = 100; // 等价于: this.a = 100; b = 101; // 等价于: this.b = 101; // 注意:this是当前对象的引用 // 访问父类的成员变量时,需要借助super关键字 // super是获取到子类对象中从基类继承下来的部分 super.a = 200; super.b = 201; // 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法 methodA(); // 没有传参,访问父类中的methodA() methodA(20); // 传递int参数,访问子类中的methodA(int) // 如果在子类中要访问重写的基类方法,则需要借助super关键字 methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到 super.methodB(); // 访问基类的methodB() } }
【注意事项】
1.只能在非静态方法中使用
2.在子类方法中,访问父类中的变量和方法
this和super之间的区别
1.this
关键字:
this
关键字用于引用当前对象的成员,包括属性和方法。- 可以用
this
来区分实例变量和方法参数或局部变量,以解决命名冲突。- 可以在构造方法中使用
this()
来调用本类的其他构造方法。- 可以在方法内部使用
this
来调用本类的其他方法。
super
关键字:
super
关键字用于引用父类的成员,包括属性和方法。- 可以在子类的构造方法中使用
super()
来调用父类的构造方法。- 可以在子类中使用
super
来调用父类的方法或属性。- 在子类中,如果没有显式调用
super()
来调用父类的构造方法,Java会默认调用父类的无参构造方法。总结:
this
关键字用于引用当前对象的成员,解决当前对象内部的命名冲突。super
关键字用于引用父类的成员,实现子类对父类的访问和调用。
访问权限
Java提供了四种访问修饰符,用于控制类、属性、方法和构造方法的访问权限。这些访问修饰符包括:
1.public
:
- 公共访问修饰符,被声明为
public
的类、属性、方法可以被任何其他类访问。- 没有访问限制,可以在任何地方访问。
2.protected
:
- 保护访问修饰符,被声明为
protected
的类、属性、方法可以被同一包内的类以及所有子类访问。- 在不同包的子类中,可以访问protected成员,但不能直接访问protected成员。
3.default
(默认,不写访问修饰符):
- 默认访问修饰符,即不写访问修饰符,被声明为默认访问修饰符的类、属性、方法只能被同一包内的类访问。
- 在不同包的子类中,不能访问默认访问修饰符的成员。
4.private
:
- 私有访问修饰符,被声明为
private
的类、属性、方法只能被本类访问,其他类无法访问。- 在同一类中可以访问private成员,但其他类无法直接访问private成员。
这些访问修饰符可以用于类、属性、方法和构造方法上,以控制对它们的访问权限。合理使用访问修饰符可以提高代码的安全性和可维护性,同时也可以隐藏实现细节,降低类之间的耦合度。
总结:
public
:公共访问权限,任何地方都可以访问。protected
:受保护访问权限,同一包内和子类可以访问。default
:默认访问权限,同一包内可以访问。private
:私有访问权限,只有本类可以访问。
继承方式
在java中,只支持以下几种方式:
单继承,多层继承,不同类继承同一个类。
final关键字
final关键可以用来修饰变量,成员方法以及类。
- 1.修饰变量或者字段,表示常量(即不能修改)
final int a=10; a=20;//编译出错
- 2.修饰类:表示次类不能被继承
final public class Animal { ... } public class Bird extends Animal { ... } // 编译出错 Error:(3, 27) java: 无法从最终com.bit.Animal进行继
继承与组合
和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。
// 轮胎类 class Tire{ // ... } // 发动机类 class Engine{ // ... } // 车载系统类 class VehicleSystem{ // ... } class Car{ private Tire tire; // 可以复用轮胎中的属性和方法 private Engine engine; // 可以复用发动机中的属性和方法 private VehicleSystem vs; // 可以复用车载系统中的属性和方法 // ... } // 奔驰是汽车 class Benz extend Car{ // 将汽车中包含的:轮胎、发送机、车载系统全部继承下来 }
完结!