从零开始学java(21)--- 继承,super和Object

Day11

今天主要了解继承,super和Object的概念。

1.继承

继承(is a)指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。
想实现继承,使用extends关键字实现。

修饰符 class A(子类) extends B(父类)
{
    //类定义部分
}

注意:
Java中只支持单根继承,每个子类只有一个直接父类。
Java的子类不能继承父类的构造构造函数,只能调用。

关于父类成员(属性或方法):

private修饰:不可继承
public修饰:可继承
(default)默认:子类与父类在同一个包,可继承,不同的包,不能继承protected修饰:受保护的,子类(可以在同一个包也可以是不同的包)中可访问父类中受保护的属性或方法。

子类构造方法调用父类的构造方法

默认隐式会调用父类无参构造方法
需要显式调用父类构造方法,使用super(),且只能出现在构造方法的第一行。与this()使用方法一样。

方法重写(override):子类中重新实现父类中的方法

子类继承了父类, 所以说子类是一个特殊的父类。
大部分时候, 子类总是以父类为基础。
额外增加新的成员变量和方法。
有些时候, 子类需要重写父类的方法,以更好的适应子类的需求。
语法规则:
1.方法名一样
2.参数列表一样
3.访问控制修饰符不能小于父类的方法 (public > protected > default >private),一般一样。
4.返回值类型要与父类中方法的返回值类型兼容(不一定一样)
如果是基本数据类型,一样。
如果父类方法返回的结果是引用类型,子类重写的方法返回值可以与父类返回值类型一致,也也可以是父类方法返回的结果的子类。
5.重写时抛出的异常不能比父类抛出的异常范围更大,如果异常是运行时异常可以和父类不一致。
实际开发中,重写方法最好和父类保持一致。

2.super:

super 是 Java提供的一个关键字, super 用于限定该对象调用它从父类继承得到的实例变量或方法。
正如 this 不能出现在 static 修饰的方法中一样, super 也不能出现在 static 修饰的方法中。
static 修饰的方法是属于类的。
该方法的调用者可能是一个类, 而不是对象, 因而 super 限定也就失去了意义。

如果子类重写了父类的方法。
则会发生子类方法覆盖父类方法的情形。
一般子类里直接访问该方法是只会访问子类重写的方法。
要想在子类中重新访问父类的方法可以用super来访问。

如果子类定义了和父类同名的实例变量。
则也会发生子类实例变量隐藏父类实例变量的情形.。
在正常情况下, 子类里定义的方法直接访问该实例变量默认会访问到子类中定义的实例变量。
无法访问到父类中被隐藏的实例变量。
在子类定义的实例方法中也可以通过 super 来访问父类中被隐藏的实例变量。

用法

super():在子类的构造方法中,super()用于调用父类的构造方法。不能和this()同时出现,因为都要求在第一行。

super.属性或方法:用于访问父类中的属性或方法,用于普通方法(除static方法)或构造方法。

3.子类的实例可以赋值给父类声明的变量(重点,理解OOP多态的关键)

如:我们先建立如下两个类Parent和Child

public class Parent {
	public void method1() {
		System.out.println("Parent Method1");
	}
}
public class Child extends Parent{
	public void Method2() {
		System.out.println("Method2");
	}
	
@Override
	public void method1() {
		System.out.println("child  method1");
	}
}

我在父类中定义了method1()方法,子类中定义了Method2()方法,重写了 method1()方法。
来进行测试:

public class TestChild {

	public static void main(String[] args) {
		Child chlid = new Child();
		chlid.Method2();
		chlid.method1();
		Parent p1=new Parent();
		p1.method1();
		Parent p2=new Child();   //重点理解,定义了一个Parent类型的变量p,赋值为Child对象。
	    //Child对象也是Parent类型 。 这是is a的体现。
		p2.method1();
		//p2.method2();这里会报错,Parent中没有定义method2()方法。
	}

}

最后输出的是:
Method2
child method1
Parent Method1
child method1

所以我们可以得出如下结论:
对于Parent p2=new Child();中的p2
1.该变量能访问到哪些方法或属性,取决于父类型(父类中声明的方法或属性可以访问)。
2.具体访问哪个取决于实例化的对象,实例化哪个对象,访问哪个对象的方法。//我们实例化的Child(),于是p2调用的是Child中重写过的method1()方法。

OOP设计原则中最重要的 Open-Close Principle(OCP)开放封闭原则

内容为设计要对扩展有好的支持,而对修改要严格限制。这是最重要也是最为抽象的原则!
因为学到了多态,涉及到了这一点就顺便提一下。
我来以例子来简单说明
创建两个基础类(不变的成分)Shape 和ShapeOpr

public class Shape {
//所有形状的父类 不变
	public void draw() {
		
	}
}
public class ShapeOpr {
//处理形状的核心逻辑类,不变
	public void paint(Shape shape) {
		shape.draw();
	}
}

这两个类我们不能做任何修改,只是拿来使用。
我们可以添加一个Shape的子类Circle,并对draw方法进行重写,来实现扩展,和扩展的要求。

public class Circle extends Shape {
	@Override
	public void draw() {
		System.out.println("draw Circle");
	}
}

而同时我们要运行是还是通过ShapeOpr中的方法来操作,而这个方法是一直不变的。
这就是开闭原则的简单体现。

4.Object

所有的类其父类都是Object

一般我们为了实现一些要求要将Object中的一些方法重写。
toString;为更好的输出信息可以重写该方法
equals: 从业务上判断两个对象是否相等,如String就重写了equals。
示例:

@Override
public boolean equals(Object obj) {
	if (this == obj) {
		return true;
	}
	// 判断变量是否是某个类型
	if (obj instanceof MyObject) {
		MyObject o = (MyObject) obj; // 强制类型转换,向下转型
		if (this.getName().equals(o.getName())) {//此处equals是String重写的。
			return true;
		}
	}
	return false;
}
<think>好的,我现在需要帮助用户理解Java的封装、继承多态这三个面向对象的基本概念,用户是零基础,所以需要从最基础的部分讲起,并且结合示例。首先,我得回顾一下用户提供的引用内容,看看有哪些可以利用的信息。 用户给出的引用中,引用[1]提到多态的具体体现,包括方法对象的多态,还有一个入门案例。引用[2]讨论了封装、继承、多态三大核心概念,以及内部类Object类。引用[3]展示了Dog类继承Animal并重写cry方法,还有独有的walk方法,这可以用于继承多态的示例。引用[4][5]也提到了三大特性,但可能内容比较分散,需要挑选合适的部分。 首先,封装。我需要解释封装的概念,为什么重要,然后给出一个Java的例子。比如,用一个类将属性私有化,提供公共的gettersetter方法。引用[5]提到封装是语法上的变形,但用户是零基础,可能需要更直观的例子,比如生类,私有属性nameage,通过方法来访问修改。 接下来是继承。引用[3]中的Dog类继承Animal的例子很好,可以借用。说明继承的作用,代码复用,子类扩展父类。需要强调extends关键字,方法重写,以及super的使用。可能还要提到不能继承私有属性方法,但用户是零基础,暂时可以不深入。 然后是多态。引用[1]中的多态案例,可以结合AnimalDog的例子,父类引用指向子类对象,调用重写的方法。同时,多态的三个必要条件:继承、重写、父类引用。可能需要区分编译时类型运行时类型,但用户是零基础,可能需要简化,用例子说明。 用户需要零基础教程,所以每个概念都要有代码示例,并且尽量简单。同时,根据用户提供的引用,确保示例与引用中的内容一致,比如引用[3]中的Dog类,这样用户如果有其他资料可以参考的话,会更容易理解。 在结构上,按照封装、继承、多态的顺序,每个部分先解释概念,再给出示例代码,最后总结作用。最后生成相关问题,可能涉及每个特性的应用场景、优缺点、实现方式等。 需要检查LaTeX格式是否正确,比如行内公式用$...$,独立公式用$$...$$。但当前问题不涉及数公式,可能不需要,但要注意用户的要求,所有行内数表达式必须使用$...$格式,如果有的话。 最后,生成的问题需要围绕这三个概念,例如封装的优点,继承的注意事项,多态的实现条件等,帮助用户进一步思考。确保问题与内容相关,并且引导用户深入理解。</think>### Java面向对象编程三大特性详解(零基础入门) #### 一、封装(Encapsulation) **概念**:将数据(属性)行为(方法)包装在类中,通过访问修饰符控制外部访问权限。 **核心作用**: - 保护数据安全性,防止误修改 - 隐藏实现细节,提供统一接口 **示例**: ```java public class Student { // 私有属性(封装) private String name; private int age; // 公共访问方法 public String getName() { return name; } public void setName(String name) { if(name != null) { // 数据校验 this.name = name; } } public int getAge() { return age; } public void setAge(int age) { if(age > 0) { // 数据保护 this.age = age; } } } ``` **特点**: - 通过`private`实现属性隐藏 - 通过`public`方法提供可控访问[^5] --- #### 二、继承(Inheritance) **概念**:子类继承父类的属性方法,实现代码复用层次化扩展。 **语法**:`extends`关键字 **示例**: ```java // 父类 class Animal { public void cry() { System.out.println("动物发出叫声"); } } // 子类 class Dog extends Animal { @Override public void cry() { System.out.println("小狗汪汪叫~"); // 方法重写 } public void walk() { // 子类扩展方法 System.out.println("摇尾巴走路"); } } ``` **特点**: - 支持方法重写(`@Override`) - 子类可添加新功能[^3] - 通过`super`调用父类成员 --- #### 三、多态(Polymorphism) **概念**:同一操作作用于不同对象时产生不同行为。 **实现条件**: 1. 继承关系 2. 方法重写 3. 父类引用指向子类对象 **示例**: ```java Animal animal = new Dog(); // 向上转型 animal.cry(); // 输出"小狗汪汪叫~" // animal.walk(); // 编译错误(父类引用无法调用子类特有方法) ``` **类型转换**: ```java if(animal instanceof Dog) { Dog dog = (Dog)animal; // 向下转型 dog.walk(); } ``` **应用场景**: - 方法参数传递父类类型 - 集合存储不同子类对象[^1][^2] --- ### 三大特性关系总结 | 特性 | 核心作用 | 典型实现方式 | |---------|---------------------------|---------------------| | 封装 | 信息隐藏,数据保护 | private/getter/setter| | 继承 | 代码复用,扩展功能 | extends/方法重写 | | 多态 | 接口统一,程序扩展性 | 向上转型/方法重写 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值