[转载] JAVA面向对象之代码块 继承 方法的重写 super关键字与重写toString()方法介绍
参考链接: 可以重写Java中的私有方法吗
JAVA面向对象之代码块与继承
代码块分类
局部代码块
作用:限制变量生命周期
书写位置:在方法中
构造代码块
开发中很少使用
书写位置:类中 方法外
调用时机:如果你有构造代码块 系统会帮你调用 帮你在创建对象时调用
静态代码块(一定是被static修饰)
依赖类 随着类的加载而加载
注意:只加载一次(系统只创建一次 不管你调用多少对象)
应用场景:U盘装载驱动程序(第二次插入U盘,不会再加载驱动程序)
加载驱动(数据库驱动 JDBC)
同步代码块(多线程)
这里暂时不做介绍 后续给予说明
代码示例
public class Demo24 {
//第三代码块
{
int a = 10;
System.out.println(a);
System.out.println("我是Demo24构造代码块");
}
public static void main(String[] args){
Person2 person = new Person2();
person.name = "张三";
person.age = 15;
person.sayHi();
System.out.println("我是main函数中得普通方法");
{
System.out.println("我是局部代码块");
}
Person2 person1 = new Person2("李四",22);
}
}
class Person2{
String name;
int age;
//第一个代码块
static {
System.out.println("我是person类的静态代码块");
}
//第二个代码块
{
//每一个对象 都会调用同一个方法 这时可以使用
sleep();
System.out.println("我是构造代码块");
}
public Person2(){
System.out.println("我是无参数的构造方法");
}
public Person2(String name, int age){
this.name = name;
this.age = age;
System.out.println("我是有参数的构造方法");
}
public String getName(){
return name;
}
public void setName(){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public void sayHi(){
System.out.println("姓名:" + name + "年龄:" + age);
}
public void sleep(){
System.out.println("睡觉");
}
}
运行结果
我是person类的静态代码块
睡觉
我是构造代码块
我是无参数的构造方法
姓名:张三年龄:15
我是main函数中得普通方法
我是局部代码块
睡觉
我是构造代码块
我是有参数的构造方法
姓名:李四年龄:22
解释
当程序运行时 会先加载Demo01.class文件,进入.class文件后,会寻找静态代码块,如果没有,会继续寻找构造代码块,由于没有
Demo24类的实例对象,所有构造代码块与构造方法均不会执行,如果另外新建一个类,Demo25,在Demo25类中建立Demo24类的实例
对象,Demo24类中的构造代码块与构造方法便会执行,之后会首先寻找main函数,找到main函数后,(局部代码块定义在方法中,在该
方法中并没有优先级)会首先遇到Person2类,遇到Person2 person = new Person2();这时会加载Person2类,
加载Person2.class文件,静态代码块与静态方法和静态属性一样,会随着类的加载而加载,存放在方法区的静态区,与对象无关,所
以在加载Person2.class文件时,会将static代码块一同加载,所有会输出'我是Person类的静态代码块',之后需要new一个对象,
继续执行Person2类中的代码,执行时,会先寻找有没有构造代码块(构造代码块存放在类中方法外,优先级高于构造方法);发现有构
造代码块,即先执行构造代码块,构造代码块中有sleep方法,故先执行sleep方法,打印'睡觉',之后执行下一句,打印'我是构造代码
块',构造代码块执行之后,会执行相应的构造方法(有参或者无参),构造代码块优先于构造方法执行,与构造代码块的位置无关,new
对象的时候没有传递参数,所有这里调用无参构造方法,打印'我是无参数的构造方法',之后回到Demo01函数,对对象中的变量进行赋
值,赋完值后,调用对象的sayHi方法,打印'姓名:张三','年龄:15',随后执行到打印语句,打印出"我是main函数中得普通方法",
之后遇到局部代码块,打印"我是局部代码块"(顺序执行),当new第二个Person2对象时,静态代码块不会再执行,即在函数运行过
程中,只会加载一次,非静态构造代码块将会继续加载,第二次new对象时候,先执行构造代码块,构造代码块中有sleep方法,所有会
先执行sleep方法,打印"睡觉",随后打印"我是构造代码块",new对象时候,传进来了参数,所有会调用Person2类中的有参数构造
方法,打印"我是有参数的构造方法",赋值后,调用sayHi方法,打印"姓名:李四年龄22",函数运行结束.
继承
继承特点
1.减少你的代码量
2.让类与类之间产生关联(产生 父子的)
继承弊端
当父类中添加新德属性时候,比如白血病,子类即使不想继承这个属性,却还是由于
继承的关系,自动得到了白血病这个属性
注意
1.继承时 可把多个类中 相同的功能或方法 抽取出来 重新构造一个类出来
把这些类建立 继承关系
2.建立继承关系的同时 一定要符合逻辑(切记不要为了继承而继承)
3.继承使用关键字:extends
举例
继承:
手机类 <打电话 发短信 玩游戏>
苹果手机类 继承 手机类 <打电话 发短信 玩游戏 爆炸>
小米手机类 继承 手机类 <打电话 发短信 玩游戏 暖手功能>
项目经理:姓名 工资 工号 分红
程序员:姓名 工资 工号
项目经理 继承 程序员 就继承了姓名 工资 和 工号 ,特有功能 分红 这样不行
不符合逻辑
应该是相同的功能抽取出来
员工类 姓名 工资 工号
项目经理 和 程序员 继承员工类 这样才符合逻辑
注意
如果是继承关系 一定符合什么是什么
项目经理是员工 子类是父类的
动物 猫 狗 马
猫 是 动物 √
动物 是 猫 ×
水果(父类) 香蕉 苹果 橘子
水果 是 香蕉 ×
香蕉 是 水果 √
继承的写法
class 子类 extends 父类{
}
代码示例
/*
* 猫类
* 姓名 颜色 种类 会睡觉 会抓老鼠
* 狗类
* 姓名 颜色 种类 会睡觉 会啃骨头
*/
// 抽取出 相同部分 组成 动物类
public class Demo02{
public static void main(String[] args){
Cat cat = new Cat();
cat.name = "汤姆";
cat.color = "灰色";
cat.kind = "灰猫";
cat.sleep();
cat.sayHi();
}
}
class Animal{
String name;
String color;
String kind;
public void sleep(){
System.out.println("睡觉");
}
public void sayHi(){
System.out.println("姓名:" + name +"颜色:" + color + "种类:" + kind);
}
}
class Cat extends Animal{
public void hitMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eatBone(){
System.out.println("啃骨头");
}
}
运行结果:
抓老鼠
睡觉
姓名:汤姆颜色:灰色种类:灰猫
JAVA中的继承
注意
1.java 只允许 单继承(多继承 可以 使用 接口 来间接实现)
2.java 中 允许 多层继承(爷爷 父亲 儿子 孙子 重孙子....)
java中 最顶层的父类(最基础类) Object类
如果我这个类没有写 继承哪个父亲 默认就是继承 Object类
1.如果我要使用 这些 类中 共有的方法(属性) 使用 哪个类?
创建当前继承中最 顶端的 类 去使用
2.如果我要使用 这些 类中 特有的方法(属性) 使用 哪个类?
创建当前继承中 最末端类 去使用
代码示例
public class Demo03 extends Object{
}
//A类 爷爷类 B类 是父亲 C类 是 孙子类
//A类中又name C类中 会叫爷爷
class A extends Object{
String name;
}
class B extends A{
}
class C extends B{
public void speak(){
System.out.println("会叫爷爷");
}
}
构造方法能不能被继承?
爷爷 父亲 儿子
爹 和 儿子 都用同一中 方法生出来 行吗? 乱
奶奶不愿意 妈妈不愿意
构造方法是不能被继承的
为了保证继承的完整性 在你创建对象的时候
如果你不调用 父类的构造方法
系统会帮你去调用 父类的无参构造方法
代码举例
public class Demo04{
public static void main(String[] args){
Son son = new Son();
son.name = "张三";
son.sayHi();
//有参构造对象
Son son2 = new Son("小明");
son2.sayHi();
}
}
class Father{
String name;
//有参 无参 构造方法
public Father(){
System.out.println("我是无参构造方法");
}
public Father(String name){
this.name = name;
System.out.println("我是有参构造方法");
}
public void sayHi(){
System.out.println("姓名:" + name);
}
}
class Son extends Father{
//无参构造
public Son(){
//如果你没有在子类的构造方法中 调用父类的构造方法
//系统会默认给你的子类构造方法中 添加一行代码
super();//调用父类的 无参构造方法
System.out.println("我是儿子类的无参构造方法");
}
//有参的
public Son(String name){
//如果你没有在子类的构造方法中 调用父类的构造方法
//系统 会默认 给你的子类 构造方法中 添加一行代码
super(); //系统帮你调用父类的构造方法
this.name = name;
System.out.println("我是儿子类的有参构造方法");
}
}
输出结果
我是爸爸类无参的构造方法
我是儿子类无参构造方法
张三
我是爸爸类无参的构造方法
我是儿子类有参的构造方法
小明
结果解释
当new一个Son对象时,由于没有传进去参数,所以会先调用儿子类的无参构造方法,
由于Son类是Father的子类,所有在子类的构造方法中会自动调用父类的无参构造方
法,从而实现Son类的实例对象同时具有Son类与Father类的属性与方法,因此先打印
父类无参构造方法中的"我是爸爸类的无参构造方法",之后返回子类构造方法,打印
子类无参构造器中得"我是儿子类无参构造方法",之后对Son的nane属性赋值,调用s
ayHi方法将姓名打出
第二次new一个Son类对象的时候,传进去姓名这个参数,所有会调用Son类中得有参
构造方法,该有参构造方法中第一句会先执行super(),即会先执行父类无参构造方
法,向上调用父类构造方法时,没有传进去参数,所有不会调用父类有参构造方法,打
印"我是爸爸类无参构造方法"后,返回子类,即Son类,打印"我是儿子类有参构造方
法",然后将姓名赋值,随后返回main函数,调用sayHi方法将name打印出来.
super关键字
super 用于指向子类对象中的父类对象(构造方法) 相当于父类的对象
super 调用对象 super.对象
super 调用方法 super.方法()
super(); 调用父类的构造方法
this(); 调用的是本类的构造方法
代码示例
public class Demo05{
public static void main(String[] args){
TestB b = new TestB();
b.fun();
}
}
class TestA{
int num1 = 10;
int num2 = 20;
public void sayHi(){
System.out.println("我是父类的sayHi方法");
}
}
class TestB extends TestA{
int num1 = 30;
public void fun(){
//使用this时 会先在本类中寻找该属性
//没找到 就去父类中找 就近原则
System.out.println(this.num1); //30
System.out.println(this.num2); //20
System.out.println(this.num3); //10
}
}
思考:如果父类中没有无参构造方法 咋整?
建议:不管是父类 还是 子类 构造方法一定要写全,避免出现问题
代码举例
public class Demo04{
}
class Phone{
String name;
public Phone(){
}
public Phone(String name){
this.name = name;
}
}
class MI extends Phone{
public MI(){
//子类的构造方法 如果你什么都不写 会默认调父类无参构造
//如果父类中 没有无参构造 就证明父类中一定有有参的构造方法
//父类构造方法无论有参 还是 无参, 子类的构造方法都必须要调用一个
//必须手动指定一个有参构造方法去调用
super("Note2");
}
public MI(String name){
super(name);
}
}
方法的重写
思考: 如果父类 和 子类的 方法 重名了,咋整?能不能重名?
答案是可以 方法的重写
注意
1.方法的声明完全一致的 叫方法的重写
2.方法的重写建立在类与类之间有继承关系(子类重写父类的方法)
Override(重写)和Overload(重载) 的区别
1.重写前提:需要继承关系
重载:在同一个类里面实现
2.重写:需要方法的声明完全一致
重载:相同的功能,不同的实现方式 只跟参数有关
代码示例
public class Demo07{
public static void main(String[] args){
IOS8 ios8 = new IOS8();
ios8.siri();
//如果直接打印对象 相当于 系统帮你打印时 调用 toString()方法
System.out.println(ios8); //输出haha
System.out.println(ios8.toString()); //输出haha
}
}
class IOS7{
public void call(){
System.out.println("打电话");
}
public void siri(){
System.out.println("说英文");
}
}
class IOS8 extends IOS7{
//方法的重写:对父类的方法 进行一个功能上的升级
//调不调父类的方法 要根据实际情况
public void siri(){
//中 英文都会说
super.siri(); //调用父类的方法
System.out.println("会说中文");
}
//重写toString()方法
//利用toString方法 来写介绍自己的方法
public String toString(){
return "haha";
}
}
重写toString()方法介绍
toString方法是Object类中的一个方法,故所有继承Object类的类,这些类中都有toString方法;
假设有一个类为Animal,他的一个对象为animal,则System.out.println(animal),
打印出来的是一个全限定类名com.lanou3g.IOS7@33909752,而打印System.out.println(animal.toString),
.lanou3g.IOS7@33909752,即包名+类名+@33909752,说明打印animal与打印animal.toString()的结果是一样的,toString()方法写完整则是
public String toString(){},即说明toString方法是有返还值的,即打印animal.t
oString()的结果,打印的是toString()函数中return语句返还的值,而打印animal
的结果又与打印animal.toString()方法的值相同,说明打印对象名所得到的结果就
是toString中return语句返还的结果,所有重写Object类中得toString方法,改变re
turn语句的返还值,然后直接打印对象名,便可以得到自己想要的结果.具体结果如上面代码所示
实例练习继承关系
需求
老师类 学生类
* 无参 有参构造 set/get方法 成员变量私有化 介绍自己的方法
属性:姓名,年龄
* 行为:吃饭
* 老师有特有的方法:讲课
* 学生有特有的方法:学习
代码实现
package com.lanou3g;
public class Demo08 {
public static void main(String[] args) {
//创建一个学生
Student student = new Student("王龙",15,1);
System.out.println(student);
Teacher teacher = new Teacher("刘",13);
System.out.println(teacher);
}
}
class Person1{
//属性
//继承中private修饰的变量 是不能直接访问的 但可以间接访问的
private String name;
private int age;
//构造方法
public Person1() {
}
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
//set/get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//特有方法
public void eat() {
System.out.println("吃饭");
}
//介绍自己的方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + name + "年龄" + age;
}
}
//学生类
class Student extends Person1{
//学号
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
//构造方法
public Student(){
}
//有参
public Student(String name, int age, int num) {
//直接调用父类的构造方法 完成赋值初始化
//为了保证继承的完整性 在子类构造方法中
//第一行 必须调用父类的构造方法(无参 有参都行)
super(name,age);
//特有属性 直接赋值就行
this.num = num;
}
public void study() {
System.out.println("学生在学习");
}
//介绍自己的方法
@Override
public String toString() {
//可以在父类的基础上 添加自己特有的属性 去打印
return super.toString() + "学号:" + num;
}
}
//教师类
class Teacher extends Person1 {
public Teacher(){
}
public Teacher(String name, int num) {
super(name,num);
}
public void teach() {
System.out.println("老师会讲课");
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
}
[转载] JAVA面向对象之代码块 继承 方法的重写 super关键字与重写toString()方法介绍相关推荐
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- Java面向对象与代码编写
Java面向对象与代码编写 面向过程的思想和面向对象的思想 面向对象和面向过程的思想有着本质上的区别, 作为面向对象的思维来说,当你拿到一个问题时,你分析这个问题不再是第一步先做什么,第二步再做什么, ...
- Java中普通代码块,构造代码块,静态代码块区别
Java中普通代码块,构造代码块,静态代码块区别及代码 示例 //执行顺序:(优先级从高到低.)静态代码块>mian方法 >构造代码块>构造方法. 其中静态代码块只执行一次.构造代码 ...
- java 面向对象三大特性之继承 万字详解(超详细)
目录 前言 : 一.为什么需要继承: 二.什么是继承(Warning : 篇幅较长)? 1.继承概述: 2.子类继承父类之后达到的效果 : ①如何使用继承? ②代码演示 : 3.继承的使用场景: eg ...
- java中static代码块_static怎样在java中修改代码块?
代码是我们每个学编程的小伙伴都接触的内容,在代码块的修改上有很多方法,那么在java中又需要使用哪种方式来对代码块进行变动呢?哦们最近在学关键字的版块,其中有一个static用来修饰代码块的效果非常不 ...
- Java面向对象三大特性之继承多态的预习笔记,are you ready? 面对疾风吧!
文章目录 继承(extends) super关键字 方法重写 instanceof关键字 abstract关键字 接口(interface) 多态 继承(extends) AextendsB A继承了 ...
- 【零基础学Java】—finally代码块(四十七)
[零基础学Java]-finally代码块(四十七)
- Java中static代码块,main函数,构造函数运行顺序
1.Java中static代码块,main函数,构造函数运行顺序如下: 答:static代码块是主动执行的,因此static代码块先执行,然后是执行构造函数,最后是Main函数. 如下例子: publ ...
- java中构造代码块、方法调用顺序问题
1. 继承的概念 继承在本职上是特殊--一般的关系,即常说的is-a关系.子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法. 2. 继承中的初始化顺序 从类的结构上而言,其 ...
最新文章
- 0基础玩转CV的利器绝了,还送万元礼金,机不可失!
- 用python画花瓣-Python:绘制樱花树
- 使用squid在阿里云服务器(centos7)上搭建自己的代理服务器
- 一个本地分支能关联两个远程仓库吗_使用git分支保存hexo博客源码到github
- 使用 Avalonia 开发 UOS 原生应用
- javascript嵌套函数和在函数内调用外部函数的区别
- java 将list按指定大小等分,最后多余的单独一份
- www.yaxjf.com+m.php,linux运维架构--PHP开发-零基础学习PHP视频教程
- php不兼容_怎么解决php不兼容问题
- latex textbf没有用_把知乎改造成LaTex创作平台
- linux fastboot 工具,fastboot工具(FastbootCommander)
- 手游和平精英透视教学
- vue-d2admin前端axio异步请求详情
- mumu模拟器切换android,MuMu模拟器“键位设置”功能详解!如有问题请联系在线客服~...
- Windows文件系统-NTFS文件系统
- 找到一个数组对象中 '某某某(属性名)'为 ['某某','某某']的值
- 【CVPR2020】Designing Network Design Spaces
- 轻便简洁的电脑录音软件,免费收藏!
- 2022-XTU程设练习1
- 低秩分解(张量分解)
热门文章
- SpringMVC那点事
- tiny4412移植tslib库
- 2.4一元多项式的表示及相加,含cpp算法
- twisted mysql_Twisted MySQL adbapi返回字典
- distinct返回null报错_C#之集合常用扩展方法与Linq
- java g1 gc ref proc_深入理解垃圾收集器的G1及日志分析
- html dom透明度,HTML DOM Style overflow 属性
- java选项设置_java环境配置
- 表字段顺序有何影响_「品味保定」炸烹虾段乾隆赞 百年保定柔雅香
- pb 怎么判断是 小数_考试90分以上的孩子是怎么学数学的?听听老师怎么说?