Java的编程之旅27——继承

1.继承的简介

继承是面向对象编程中的一个重要概念,指的是一个类可以继承另一个类的属性和方法。被继承的类称为父类或基类,继承这个父类的类称为子类或派生类。

通过继承,子类可以继承父类的属性和方法,使得子类具有相似的行为和特性。子类可以重写父类的方法,覆盖父类的行为,也可以添加新的属性和方法以扩展父类的功能。

继承提供了代码复用的机制,可以减少代码的冗余,并且使得代码更加可维护和扩展。此外,继承也是实现多态的基础,通过父类的引用可以调用子类的方法,实现不同对象的统一操作。


2.代码中的体现

定义一个名为“Person”的类,作为父类 

public class Person{String name;int age;public Person(){}public Person(String name ,int age){this.name = name;this.age = age;}public void eat(){System.out.println("人会吃~");}public void sleep(){System.out.println("人会睡~");}}

这段代码定义了一个名为Person的类。Person类包含了两个属性:name(姓名)和age(年龄)。类中定义了两个构造方法:一个无参构造方法和一个带有参数的构造方法,用于初始化name和age属性。

类中还定义了两个方法:eat(吃)和sleep(睡)。这两个方法是公共的(public),可以被其他类调用。eat方法输出了一个字符串,表示人会吃;sleep方法输出了一个字符串,表示人会睡。

这个Person类是一个基类,其他类可以通过继承这个类来继承其中的属性和方法。通过继承,子类可以使用Person类中定义的属性和方法,并可以根据需要进行扩展和修改。

定义一个名为“Teacher”的子类用来继承“Person”

public class Teacher extends Person{int teachAge;//构造方法public Teacher(){}public Teacher(int teachAge) {TeachAge = teachAge;}public Teacher(String name,int age,int teachAge){super(name, age);TeachAge = teachAge;}public void teach(){System.out.println("老师会教书");}
}

这段代码定义了一个名为Teacher的类,它继承自Person类。Teacher类有一个额外的实例变量teachAge,表示教学年龄。

代码中提供了三个构造方法:

  1. 无参构造方法:没有参数,什么也不做。
  2. 带参构造方法:接受一个int类型的teachAge参数,并将其赋值给Teacher类的实例变量teachAge。
  3. 带参构造方法:接受一个字符串name、一个int类型的age和一个int类型的teachAge参数,并将name和age传递给父类Person的构造方法进行初始化,同时将teachAge赋值给Teacher类的实例变量teachAge。

Teacher类还有一个公共方法teach(),它打印出"老师会教书"的消息。

这段代码实现了一个教师类,继承了人类,具有教学年龄的特征,并能够进行教学操作。

最后定义一个功能测试类

public class Test {public static void main(String[] args) {Person person = new Person("hh",22);System.out.println(person.name+","+person.age);person.eat();person.sleep();Teacher teacher = new Teacher("jj",56,12);System.out.println(teacher.name+","+teacher.age+","+teacher.TeachAge);teacher.eat();teacher.sleep();teacher.teach();}
}

输出结果: 

这段代码定义了一个名为Test的类,其中有一个main方法作为程序的入口点。

在main方法中,首先创建了一个Person对象,通过调用Person类的带参构造方法,传入字符串"hh"和整数22进行初始化。然后通过person对象访问其实例变量name和age,并将结果打印出来。接着调用person对象的eat()方法和sleep()方法,输出对应的消息。

接下来,创建了一个Teacher对象,通过调用Teacher类的带参构造方法,传入字符串"jj"、整数56和整数12进行初始化。然后通过teacher对象访问其父类Person中的name和age实例变量,以及Teacher类自身的TeachAge实例变量,并将结果打印出来。接着调用teacher对象的eat()方法和sleep()方法,输出对应的消息。最后通过调用teacher对象的teach()方法,输出"老师会教书"的消息。


3.super关键字的用法

1.定义一个名为“Father”的父类

public class Father {String name;int age;public Father() {}public Father(String name, int age) {this.name = name;this.age = age;}public void eat(){System.out.println(this.age+"岁的"+this.name+"会吃");}
}

这段代码定义了一个名为Father的类。Father类有两个实例变量name和age,代表父类成员中的姓名和年龄。

Father类有两个构造方法,一个是无参构造方法,一个是有参构造方法。无参构造方法不进行任何操作,而有参构造方法用于初始化父类成员的姓名和年龄。

Father类还有一个eat()方法,用于输出年龄和姓名,并打印一句话表示吃的动作。

2.定义一个名为“Child”的子类用来继承“Father”父类

public class Child extends Father{String name;int age;public Child() {}public Child(String name, int age) {this.name = name;this.age = age;}public Child(String name, int age, String name1, int age1) {super(name, age);this.name = name1;this.age = age1;}public void eat(){//所表达的是子类中的“xx岁的xx会吃”System.out.println(this.age+"岁的"+this.name+"会吃");//表达父类中的”xx岁的xx会吃“System.out.println(super.age+"岁的"+super.name+"会吃");//还可以用super关键字直接调用父类中的方法//super.eat();}
}

这段代码定义了一个名为Child的类,它继承自Father类。Child类也有两个实例变量name和age,但是它们与父类的name和age变量没有任何关系。

Child类有三个构造方法,一个是无参构造方法,一个是有两个参数的构造方法,另一个是有四个参数的构造方法。其中有两个参数的构造方法用于初始化子类自己的name和age变量,四个参数的构造方法不仅会调用父类的有参构造方法来初始化父类的name和age变量,还会初始化子类的name和age变量。

Child类也有一个eat()方法,但是与父类的eat()方法不同的是,它重写了父类的eat()方法。在重写的eat()方法中,首先输出子类自己的年龄和姓名,并打印一句话表示吃的动作。然后使用super关键字调用父类的age和name变量,并打印一句话表示父类的吃的动作。最后还可以使用super关键字直接调用父类的eat()方法。

3.定义一个测试类

public class Test {public static void main(String[] args) {Father father = new Father("老贺",40);father.eat();Child child = new Child("小贺",18);child.eat();}
}

注意:输出结果的后一行有点反常,这是因为只调用了Child类中的public Child(String name, int age)方法,而这是属于子类中的方法,和父类没有关系

 public void eat(){//所表达的是子类中的“xx岁的xx会吃”System.out.println(this.age+"岁的"+this.name+"会吃");//表达父类中的”xx岁的xx会吃“System.out.println(super.age+"岁的"+super.name+"会吃");//还可以用super关键字直接调用父类中的方法//super.eat();}

所以eat()方法中后一个语句输出的是父类中所定义的值,要想正常输出,则需要重新new一个child

对象,用来调用public Child(String name, int age, String name1, int age1) 这个构造方法

更改后的主函数: 

public class Test {public static void main(String[] args) {Father father = new Father("老贺",40);father.eat();Child child = new Child("小贺",18,"老贺",40);child.eat();}
}

输出结果


4.继承中的权限

在Java中,继承中的权限是通过访问修饰符来控制的。Java中有四种访问修饰符:public、protected、default和private。

  1. public:被public修饰的成员(字段、方法、构造方法等)可以在任何地方被访问,包括其他类、不同包中的类和子类。

  2. protected:被protected修饰的成员可以被同一个包中的类访问,也可以被不同包中的子类访问,但不能被不同包中的非子类访问。

  3. default:没有修饰符的成员(也称为包级访问)可以被同一个包中的类访问,但不能被不同包中的类访问。

  4. private:被private修饰的成员只能在同一个类中访问,不能被其他类或子类访问。

继承关系中,子类会继承父类的字段和方法。下面是不同访问修饰符下,子类对父类成员的访问权限:

  • public成员:子类可以访问父类的public成员。

  • protected成员:子类可以访问父类的protected成员,即使子类和父类不在同一个包中。

  • default成员:子类可以访问父类的default成员,但是要求子类和父类在同一个包中。

  • private成员:子类无法直接访问父类的private成员,只能通过父类的public/protected/default方法来间接访问。

需要注意的是,子类可以覆盖(重写)父类的方法,但是子类不能降低父类方法的访问权限。也就是说,如果父类的方法是public,那么子类重写该方法时也必须使用public修饰符。同样地,如果父类的方法是protected,子类重写该方法时可以使用protected或public修饰符,但不能使用private修饰符或不使用任何修饰符(default)。

这样设计的目的是为了保护类的封装性和安全性,子类只能通过继承和重写的方式来访问和修改父类的成员。

public class Fu {public String varPub = "我是公成员变量";private String varPri = "我是私有成员变量";protected String varPro = "我是受保护的变量";String varDef = "我是默认的变量";
}
public class Zi extends Fu{public void method(){System.out.println(this.varPub);//System.out.println(this.varPri);System.out.println(this.varPro);System.out.println(this.varDef);}
}
public class TS {public static void main(String[] args) {Fu fu = new Fu();System.out.println(fu.varPub);System.out.println(fu.varPro);System.out.println(fu.varDef);//System.out.println(fu.varPri);//除了private,其他权限都可在当前包内的其他类中都可访问System.out.println("============");Zi zi = new Zi();zi.method();//同包子类中,除私有权限外都可调用}
}

 在另一包内在定义一个子类

public class Zi extends Fu {public void method(){System.out.println(super.varPub);//System.out.println(super.varPri);System.out.println(super.varPro);//System.out.println(super.varDef);//不同包子类,只有公有和受保护变量可以被调用}
}
public class Ts {public static void main(String[] args) {Zi zi = new Zi();zi.method();}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/487959.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【线程池项目(二)】线程池FIXED模式的实现

在上一篇【线程池项目(一)】项目介绍和代码展示 中,我们展示了线程池的两个版本实现,它们的代码在具体的实现细节上是优化过了的。下文提供的代码并非完整,也有很多地方尚需改善,但这些差异对理解整个项目而…

靡语IT:JavaScript数组

目录 1.数组:Array 2.Array.length 3.数组的声明(创建)方法 4.数组去重 5.数组遍历 6.类数组对象 1.数组:Array 数组对象的作用是:使用单独的变量名来存储一系列的值。 参数 参数 size 是期望的数组元素个数。返回的数组&#xff0…

操作系统(1)——学习导论(Ⅰ)

目录 小程一言专栏链接: [link](http://t.csdnimg.cn/6grrU) 学习导论什么是操作系统主要功能强调 操作系统历史硬件层面处理器重要特点and功能 存储器磁盘I/O设备小程常用的I/O设备及其特点 小程一言 本操作系统专栏,是小程在学操作系统的过程中的第一步&#xff…

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了

谷歌刚刷新大模型上下文窗口长度记录,发布支持100万token的Gemini 1.5,微软就来砸场子了。 推出大模型上下文窗口拉长新方法——LongRoPE,一口气将上下文拉至2048k token,也就是200多万! 并且1000步微调内&#xff0c…

【刷题记录】链表的回文结构

本系列博客为个人刷题思路分享,有需要借鉴即可。 1.题目链接: LINK 2.详解思路: 思路:思路:先找到中间节点,然后逆置后半部分链表,一个指针指向链表的头节点,再一个指针指向逆置的头…

ELK介绍以及搭建

基础环境 hostnamectl set-hostname els01 hostnamectl set-hostname els02 hostnamectl set-hostname els03 hostnamectl set-hostname kbased -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config systemctl stop firewalld & systemctl disable firewalld# 安…

c语言的数据结构:找环状链表入口处

一起<(&#xffe3;︶&#xffe3;)↗[GO!] 1.如何判断一个链表是否有环 思路:设定两个快慢指针fast和slow,fast每次走两个结点,slow每次走一个节点 如果fast指针遇到了Null,那么这个链表没有环,如果fast和slow可以相遇,则代表这个链表有环 代码如下 N:fast先进环,slow后…

鼠标右键助手专业版 MouseBoost PRO for Mac v3.3.6中文破解

MouseBoost Pro mac版是一款简单实用的鼠标右键助手专业版&#xff0c;MouseBoost Pro for Mac只要轻点你的鼠标右键&#xff0c;就可以激活你想要的各种功能&#xff0c;让你的工作效率大幅度提高&#xff0c;非常好用。 软件下载&#xff1a;MouseBoost PRO for Mac v3.3.6中…

leet hot 100-2 字母异位词分组

字母异位词分组 原题链接思路代码 原题链接 leet hot 100-2 49. 字母异位词分组 思路 要求把含有相同字母的放到一起&#xff0c;我们可以遍历每一个字符串 将他们重新排序&#xff0c;将排序完是一样的字符串放在一起 用无序容器存放起来 然后遍历这个无序map容器将排序后相…

解决数学计算公式在前端项目里的展示,涉及换肤适配各个框架

有时候我们项目里面会嵌套一些数学公式说明 例如 可能你会发现市面上有很多的第三方库可以实现&#xff0c;比如&#xff1a; MathJax&#xff1a; https://www.mathjax.org/ 但是我们项目里面用到公式可能就一个页面&#xff0c;引一个第三方库进来会显得十分臃肿&#xff0…

JavaScript原型继承与面向对象编程思想

原型继承与面向对象编程思想 在JavaScript中&#xff0c;原型(prototype)、构造函数(constructor)和实例对象(instance)是面向对象编程中的重要概念&#xff0c;并且它们之间存在着紧密的关系。 原型(prototype)&#xff1a;原型是JavaScript中对象之间关联的一种机制。每个Ja…

c++笔记理解

1.封装 &#xff08;1&#xff09;构造函数不是必须在的 可以通过行为修改属性 &#xff08;2&#xff09;private和protected区别在于继承那里要学 &#xff08;3&#xff09;类默认是私有&#xff0c;struct是共有 私有的好处&#xff1a;控制数据的有效性&#xff0c;意…