Java学习的第二篇总结!——子类和父类 深入分析,希望大家多多支持!
从内存角度去分析代码,可以从本质上理解一门语言!
子类从父类继承分成两种:
1.方法的继承:
方法的继承,父类直接把自己的方法转移到子类中去,当然前提是父类的方法修饰符的访问范围是子类可以访问的范围,但是如果子类已经重写了父类的方法,这时候这个方法就不能重父类转移到子类中。
2.成员变量的继承 :
成员变量就会有点奇妙了,它不会从父类转移到子类,而是保留在父类中,这就会出现,子类和父类可能同时拥有两个相同名字的变量。
下面用一段代码来说明这种相对比较复杂的关系:
package com.text;
public class Test {
public static void main(String[] args) {
Father a = new Father();
Chilren b = new Chilren();
Father c = new Chilren();
a.getAge();
System.out.println(a.age);
b.getAge();
System.out.println(b.age);
c.getAge();
System.out.println(c.age);
}
}
class Father {
int age = 40;
public void getAge() {
System.out.println(age);
}
}
class Chilren extends Father {
int age = 18;
public void getAge() {
System.out.println(age);
}
}
输出
40
40
18
18
18
40
前四个结果可以理解,但是最后两个结果有人可能会问为什么结果会不一样,这段代码就体现了,成员变量继承和方法继承的区别。
可以得出结论:
Father c = new Chilren();
在以上父类引用指向子类对象情况下,访问变量看的是引用类型,所以c.age是父类的成员变量,而c.getAge()访问到的是子类Chilren的方法,所以在这个方法中用到的age变量是Chilren的变量
反正一句话,访问变量看声明,访问方法看实际对象类型(new出来的类型)
接下来对代码做部分修改
public static void main(String[] args) {
Chilren b = new Chilren();
Father c = b
System.out.println(b.age);
System.out.println(c.age);
}
输出
18
40
b 和c 两个引用都是指向内存中同一个对象,但是打印出来的结果却是不同,这就说明了,内存中保存了两个 age的值,一个是18 一个是40 。
这里就会产生一些疑问,在内存中他们是怎么存储的?这时候会想到有个super关键字,通过super. 可以访问到父类的变量和方法,这里有人会说:“super.代表的就是一个父类对象,因为他指向父类” 之前我也是这么想,但是看过一些书后知道其实不是这样
其实super.不是“东西”,说道super.自然会想到this.,有人把他们归为同类,其实他们大大不同
this:是一个真真实实对象,代表的就是当前对象,可以用 return this; 去返回一个对象。
super:不能一个对象,不是指向父类对象的意思,super只是修饰了他后边的内容,告诉JVM,后面这部 分内容不是当前对象所属类的内容而已,若用return super,JVM是不允许的,是一种错误的语法。
Chilren b = new Chilren();
Father c = b
回归到上面这段代码,这里并不是说内存中有两个对象 b 和 c ,内存中其实就只有一个 b对象 ,只是c 不仅有自己的实例 变量,同时也存在父类所定义的全部实例变量。
所以可以得出结论:在实例化一个子类的同时,系统会给子类所有实例变量分配内存,也会给他的父类的实例变量分配内存,及时父子类中存在重名的实例变量,也会两个都分配内存的,这个时候子类只是隐藏了父类的这个变量,但还是会给它分配内存,然后可以用super来访问属于父类的变量。
分享到:
相关推荐
这一过程是自动且安全的,因为子类对象包含了父类的所有属性和方法。下面我们将深入探讨这个主题,包括它的原理、示例代码以及相关的知识点。 首先,理解向上转型的基本概念。在Java中,子类是父类的一个特例,这...
本文将深入探讨在继承中的程序执行顺序,以及子类与父类的执行顺序问题。 首先,我们需要了解Java或Python等面向对象语言中类的构造过程。当一个类实例化时,其构造函数(在Java中是`构造器`,在Python中是`__init_...
这里我们将深入探讨如何在 C# 中进行父类属性到子类属性的赋值,并考虑效率、灵活性和代码可维护性。 首先,让我们理解一下父类和子类的概念。在 C# 中,父类(也称为基类或超类)是定义了一组属性和方法的类,而...
总结,理解和正确使用“在父类获取子类属性”这一概念是Java编程中一个重要的技能,它涉及到继承、封装和多态等面向对象编程的核心概念。在实际应用中,我们需要根据具体场景选择合适的方式来访问和操作子类的属性,...
标题“javase子类父类继承关系图解”指的是对这一概念的可视化展示,帮助初学者更好地理解Java中的继承机制。 Java成员初始化顺序对于理解和正确使用继承至关重要。当创建一个子类对象时,其内存加载顺序遵循以下...
当我们谈论子类与父类(也称为基类)的关系时,继承机制允许子类继承父类的属性和方法。在某些情况下,我们需要在子类中调用父类的方法,以便于扩展或覆盖原有功能。这里我们将深入探讨如何使用`Object....
在C++编程语言中,`...理解子类对象不能直接调用父类虚函数这一概念,有助于避免编程中的常见错误,并能更好地利用C++的面向对象特性。在实际编程中,应始终通过基类指针或引用调用虚函数,以确保多态性的正确行为。
在这个"圣诞树代码编程python-23-子类重写父类同名属性和方法"的主题中,我们将深入探讨如何在子类中重写父类的同名属性和方法,以实现特定的功能定制。 首先,让我们了解什么是属性和方法。属性是类中用于存储数据...
本课程设计的主题是“子类调用父类同名方法和属性的代码实现”,我们将深入探讨这个主题。 在Python中,子类通过`class SubClass(ParentClass):`的方式定义,这里的`SubClass`是子类,`ParentClass`是父类。子类...
本课程设计的主题是"子类调用父类同名方法和属性的思路分析",我们将深入探讨这一主题,理解Python中如何处理这种情况。 在Python中,子类可以通过`super()`函数来调用父类的方法和属性。`super()`函数是内置的魔法...
本主题围绕“子类调用抽象父类”展开,我们将深入探讨抽象类、子类继承、抽象属性以及如何在子类中重写父类的方法。 首先,让我们理解什么是抽象类。在Java、C#等面向对象编程语言中,抽象类是一种特殊的类,它不能...
至于标签"源码"和"工具",这可能意味着深入理解JVM的内部工作原理,以及使用诸如IDE或调试工具来查看和分析类的元数据和内存布局是有助于进一步掌握这个概念的。例如,通过反编译工具如JAD或使用Java的反射API,我们...
本文深入探讨了Java语言中的继承机制,并重点分析了父类与子类之间的关系。文章围绕子类继承父类成员的过程、成员变量及方法的赋值、重写、覆盖等问题展开讨论,旨在帮助读者更好地理解Java继承中的重点与难点。 ##...
在Java编程中,对象类型转换和`instanceof`运算符是两...通过深入理解这些概念,我们可以编写出更高效、更易于维护的面向对象程序。在编写代码时,一定要注意类型转换的风险,并合理使用`instanceof`来避免潜在的异常。
在Python编程语言中,继承是面向对象编程的一个核心特性,它允许子类(派生类)从父类(基类)那里获得属性和方法,从而实现代码的复用和扩展。这里我们将深入探讨单继承、多继承以及多层继承的概念、语法以及相关...
首先,让我们深入理解Java继承的概念。当一个子类继承一个父类时,子类就自动获得了父类的所有非私有(public和protected)成员,包括字段和方法。这使得子类能够共享父类的功能,同时还可以添加自己的特性和行为。...
本文将深入探讨Java中的多态性,特别是“父类引用子类对象”的概念,以及这一特性如何在实际编码中体现。 ### 多态性概述 多态性主要通过方法的重写(Overriding)、重载(Overloading)和动态绑定(Dynamic Binding)来...
总之,这个案例提供了一种高效的方法,利用Java反射机制在子类和父类之间进行字段赋值,减少了手动编写赋值代码的需求,提高了代码的可维护性和性能,尤其是在处理大量数据持久化或查询结果映射时。通过深入理解并...
当然,使用元类需要谨慎,因为它涉及到对Python类创建过程的深入理解,且过度使用可能导致代码难以理解和维护。在大多数情况下,直接引用父类或使用`super()`已经足够,但在特定场景下,元类能提供更高级的控制。
本文将深入探讨如何在子类中引发基类的事件,这是面向对象编程中的一个关键概念。 首先,我们需要理解事件的基本原理。在VB 2010中,事件通常由控件或自定义对象生成,然后由事件处理程序接收并处理。事件的发生...