继承

1.继承是类和类之间的一种关系java中的类和类之间的关系有很多中,继承只是其中一种,其他的还有依赖、组合、聚合等2.继承关系的俩个类,一个是子类,一个是父类子类也可以称为派生类,父类也可以称为基类子类继承父类使用关键字extends来表示。例如:public class Student extends Person{}3.子类和父类之间,从意义上来说,需要有"is a"的关系例如:public class Student extends Person{}注意:student is a person例如:public class Dog extends Animal{}注意:dog is a animal注意,对于A类和B类之间的继承这种关系,不仅要从语法角度去考虑怎么编写,还要从意义这个角度去考虑: A类和B类之间有继承关系是否合适。例如,从语法上讲,一个类可以继承任何的另一个类,只要满足语法要求即可,但是从意义上来考虑的话,这种继承关系可能并不合适。这个关系是否合适,可以使用"is a"先做出一个基本的判定。4.java中的【类和类】之间的继承,是单继承类和类之间、接口和接口之间都可以有继承关系但是类和类之间,是单继承接口和接口之间,是多继承注意,类和接口之间可以有【实现】的关系单继承指的是,一个类只能有一个【直接】的父类型,但是一个类可能会有很多个超类,超类指的是一个类的父类型的父类型,以及再往上的父类型。java中任何一个类(除了Object),都是有且只有一个【直接】继承的父类型,除此之外,一个类还可以有很多【间接】继承的父类型。注意,虽然一个类只能【直接】继承一个父类型,但是一个父类型可以被多个不同的类继承,也就是一个父类可能会有很多【直接】的子类型。5.父类中的属性和方法,可以被子类继承一个子类继承了父类,那么就可以继承父类中的属性和方法,但是在子类中是否可以【直接】使用这些属性和方法,需要看这些属性和方法在父类中原有的访问权限修饰符是什么。控制类、属性、方法是否可以被访问的修饰符有:public protected default private例如:父类中的属性和方法使用了public修饰,那么在子类中就【可以直接】使用父类中的属性和方法使用了private修饰,那么在子类中就【不可以直接】使用注意,父类中无论是public修饰的还是private修饰的属性和方法,都是会被子类继承的,只是在子类中能不能直接访问这些属性和方法,就和这些修饰符有关系了。子类继承父类后,在子类中,怎么才能算是可以直接访问父类中的属性和方法?例如:public class Person{private String name;public int age;private void say(){}public void run(){}}public class Student extends Person{private String msg;//在子类中,是否可以直接访问从父类中继承过来的属性和方法public void test(){//访问子类自己的属性System.out.println(msg);//【直接】访问父类中继承过来的age属性System.out.println(age);//报错,name是父类中私有属性,在子类中不能直接访问//System.out.println(name);//【直接】调用父类中继承过来的run方法run();//报错,say方法是父类中私有方法,在子类中不能直接访问//say();}}注意,父类中的构造器,是不能被子类继承的,但是在子类的构造器中,可以调用父类的构造器,需要使用super关键字。注意,子类调用父类的构造器有俩种情况:1.隐式调用如果父类中【有】默认的无参构造器,那么在子类的构造器中就会隐式的自动调用父类中的默认无参构造器例如:public class Person{//父类中的无参构造器public Perosn(){}}public class Student extends Person{public Student(){//在这里,就会默认自动调用父类的无参构造器//这种方式就是隐式调用}}2.显示调用如果父类中【没有】默认的无参构造器,那么在子类中就需要我们显式的手动调用父类中的有参构造器例如:public class Person{//父类中的有参构造器public Perosn(String name){}}public class Student extends Person{public Student(){//这时候,无法隐式自动调用,因为父类中没有无参构造器//必须手动显式调用父类中的构造器super("tom");}}注意,隐式调用和显式调用父类中的构造器,区别在于有没有把调用父类构造器的那一句代码给写出来。注意,没有写出来的话,那么就是默认的隐式调用,但是隐式调用只能调用父类中无参的构造器,如果父类中没有无参构造器,这时候就会报错了。5.Object类每个类如果没有显式的指定它的父类型,那么编译就默认直接继承了Object类。例如:public class Student{}编译后变为:public class Student extends Object{}所以,java中的每一个类都是直接或者间接的继承了Object类,并且每一个对象和Object都有"is a"的关系,//一切皆为对象anyObj is a ObjectanyObj instanceof Object // true注意,任意对象也包含数组对象Object中已经提供了一个对象应该具备的最基本的方法,所以java中的任意对象,都可以调用到从Object中继承了最基本的方法,例如:toString equals getClass hashCode wait notify clone等思考:继承有什么好处?思考:子类构造器中为什么要调用父类的构造器?子类继承了父类,那么就把父类中的属性和方法都继承了过来,但是我们希望子类中继承过来的属性都是已经在父类中完成了初始化工作之后的,因为这样我们就可以拿着这些属性直接使用了,父类中对这些属性完成初始化工作的代码默认就在构造器中,所以我们子类构造器里面首先会调用父类中的构造器,先完成对父类中属性的初始化工作,然后再执行子类自己的构造器中的代码,如果我们对父类构造器中初始化的工作不满意,那么我们还可以在子类构造器的代码中对继承过来的属性进行修改,以便覆盖掉父类初始化的值。

super关键字

 子类继承父类之后,在子类中可以使用关键字this表示访问子类中的属性、方法、构造器,也可以在子类中使用super关键字表示访问父类中的属性、方法、构造器。1.访问父类中的属性例如:public class Person{protected String name = "zs";}public class Student extends Person{private String name = "lisi";public void test(){System.out.println(name);//注意,这时候this和super可以区分访问的是哪个nameSystem.out.println(this.name);System.out.println(super.name);}}注意,如果父类中的属性,是private修饰的,那么使用super也是不能访问的。例如:public class Person{//注意父类中属性的修饰符private String name = "zs";}public class Student extends Person{private String name = "lisi";public void test(){//编译报错,无法访问父类中private修饰的属性System.out.println(super.name);}}注意,如果父类中的属性name被继承了,子类中有写了一个自己的属性那么,那么这时候this和super就可以区分我们访问的name到底是哪一个name属性注意,如果父类中的属性name被继承了,子类中也没自己定义新的name属性,那么这时候,直接使用name和this.name和super.name这三种方式访问都是同一个name属性例如:public class Person{//注意父类中属性的修饰符public String name = "zs";}public class Student extends Person{public void test(){//编译都通过,且访问的同一个name属性//就是从父类中继承过来的name属性System.out.println(name);System.out.println(this.name);System.out.println(super.name);}}2.调用父类中的方法例如:public class Person{public void run(){System.out.println("person run..");}}public class Student extends Person{public void run(){System.out.println("student run..");}//在这里可以访问到自己类中的run方法//也可以访问到父类中的run方法//为了区分调用的是哪一个run方法//可以使用this和superpublic void test(){run();this.run();super.run();}}注意,如果调用或访问的时候,没有因为同名而带来的歧义的话,可以不使用this或者super,直接通过方法名或者属性名进行调用就可以了。3.调用父类中的构造器例如:public class Person{}public class Student extends Person{//编译通过//默认使用super()调用父类中的无参构造器//隐式调用public Student(){}}例如:public class Person{protected String name;public Person(String name){this.name = name;}}public class Student extends Person{//编译报错//因为默认执行的代码是super()//但是父类中已经没有了无参构造器public Student(){}}例如:public class Person{protected String name;public Person(String name){this.name = name;}}public class Student extends Person{//编译通过//手动使用super调用父类中的有参构造器//显式调用public Student(){super("tom");}}注意,无论是隐式调用还是显式调用父类中的构造器,super语句一定要出现在子类中构造器中的第一行代码。例如:public class Person{protected String name;public Person(String name){this.name = name;}}public class Student extends Person{//编译报错//使用super调用了父类构造器,但是它不是第一行代码public Student(){System.out.println("子类构造器被调用");super("tom");}}注意,在子类的构造器中,可以使用this()来调用子类其他的构造器,也可以使用super()来调用父类中的构造器,但是这俩种用法不能同时出现,因为它们俩个任何一个出现都要放在构造器中的第一行代码的位置。总结:在创建一个子类对象的时候,肯定要调用到子类中的一个构造器,并且在子类构造器执行之前,一定是会先调用到父类中的构造器的。这样做的目的就是在子类的构造器执行之前,先执行父类的构造器完成对父类中属性的初始化,保证子类继承过来的父类中的属性是已经初始化好可以直接使用的。注意,this在类中是可以打印输出的,但是super不能public class Student{public void test(){System.out.println(this);//编译通过System.out.println(super);//编译报错,语法不支持}}30.16 方法的重写(覆盖)简单的理解,重写就是子类继承了父类中的某一个方法,然后在子类中又把这个方法重新定义了一遍。只不过在这个过程中,我们需要注意一些细节和规则。1.方法的重写,存在于子类和父类之间(可以是直接父类,也可以是间接父类),之前学习过的方法重载,是存在于同一个类中。方法的重载:同一个类中方法的重写:子类和父类之间2.类中静态方法和非静方法,对重写的影响父类中的静态方法,不能被子类中重写为非静态方法,编译报错错误信息:被覆盖的方法为static父类中的非静态方法,不能被子类中重写为静态方法,编译报错错误信息:覆盖的方法为static父类中的静态方法,子类可以继承,子类中也可以定义一个和父类中相同名字的静态方法,但是这个不是重写。 编译通过重写只能发生在子父之间非静态方法上。因为静态方法是属于类的,可以类名直接调用,它和对象没有关系的。父类中的非静态方法,可以被子类中继承并且重写,但是重写的时候也必须是非静态方法。这个就是正常的方法重写现象。3.父类中的私有方法不能被子类重写子类继承父类后,同时也继承到了父类中的方法,如果需要对某个方法进行重写,这个被继承的方法需要满足以下条件:必须是非静态的方法该方法在子类中必须是可以直接访问的注意,父类中的一个方法,它的修饰符可能是以下几种:public      子类中继承后一定可以直接访问protected 子类中继承后一定可以直接访问default       子类中继承后可能可以直接访问子父类同包,则可以直接访问子父类不同包,则不可以直接访问private     子类中继承后一定不可以直接访问注意,能直接访问就说明这个继承过来的方法可以重写,不能直接访问则说明不能重写。例如:public class Person{private void test(){}}//编译通过,但是【不是重写】,只是在俩个类中有各自的一个私有方法,只是这个俩个私有方法的名字和参数列表相同而已。public class Student extends Person{private void test(){}}4.方法重写的语法要求方法名必须相同参数列表必须相同访问控制修饰符可以相同,也可以不同,如果不同的话,只能扩大,不能缩小public > protected > default > private方法抛出的异常可以相同,也可以不同,如果不同的话,只能缩小,不能扩大注意,异常类型的范围大小,是根据异常类型中的子父类关系来确定,例如 Exception异常类型是ArraysIndexOutOfBoundsException异常类型的父类型,所以 Exception异常类型的范围比ArraysIndexOutOfBoundsException异常类型的范围大。子类异常范围小,父类型异常范围大。如果返回类型是引用类型:方法的返回类型可以相同,也可以不同,如果不同的话,重写之后方法的返回类型必须是原方法的返回类型的子类型(兼容)例如:public class Person{public Object test(){return null;}}public class Student extends Person{//编译通过,保持一致可以public Object test(){return null;}//编译通过,返回类型和原方法返回类型兼容也可以public String test(){return null;}}如果返回类型是基本类型:重写后的方法的返回类型必须和父类中原方法保持一致。例如:public class Person{public int test(){return 0;}}public class Student extends Person{//编译通过,重写后必须和原方法的返回类型保持一致public int test(){return 0;}//编译报错public long test(){return 0;}//编译报错public byte test(){return 0;}//编译报错public short test(){return 0;}}注意,在绝大数重写情况下,方法的修饰符、返回类型、方法名、参数列表、抛出异常这几个部分,子类中重写的方法默认情况下都是和父类中的方法保持一致的。思考1,如果各个部分都和父类中方法保持一致,那么这个方法的重写,我们重写的是什么?我们主要重写的是方法中的代码,所以大多数情况方法声明部分和父类中的方法保持一致。//方法的声明public void test();//方法的声明和方法的实现//重写的是方法的实现public void test(){}思考2,为什么要对从父类中继承过来的方法进行重写?子类中继承过来的方法,原来是定义在父类中的,现在被子类继承了,而子类本身又是对父类型的扩展,所以这个时候,从父类中继承过来的方法,可能在子类中已经不是很适用了,所以我们需要重写对这个方法进行重写。或者说子类中不满意原来父类中对这个方法的实现,那么在子类中就需要对这个方法进行重写例如:通过这个例子,说明了为什么在程序中会进行重写,以及重写之前和重写之后,对方法的调用有什么影响public class Person{public void sayHello(){System.out.println("你好!");}}public class Student extends Person{public void sayHello(){System.out.println("hello! memeda");}}main:Student stu = new Student();//注意,如果子类中没有重写sayHello方法,那么这里调用的就是从父类中继承过来的sayHello方法//如果子类中重写了sayHello方法,那么这里调用的就是重写之后的sayHello方法stu.sayHello();例如:java-se api中的Object和String的示例//toString方法定义在Object中//java中所有类都是Object的子类//任何类的对象都可以调用到toString方法//toString方法的作用就是返回当前对象的默认字符串形式public class Object{public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}}//String继承了Object//从而继承到了toString方法//因为字符串本身已经是字符串了,所以不需要返回Object中toString方法里面定义的对象默认的字符串形式//所以String类对toString方法进行了重写//重写的代码中,把字符串自己本身(this)返回,因为这个字符串对象自己已经是一个字符串了public class String extends Object{/*** This object (which is already a string!) is itself returned.** @return  the string itself.*/public String toString() {return this;}}main:String str = "hello";str.toString();

Java中面向对象的三大特征之一——继承相关推荐

  1. java的知识点11——面向对象的三大特征之一继承、instanceof 运算符、方法的重写override、Object类基本特性、toString方法

    面向对象的三大特征:继承.封装.多态 继承的实现 继承让我们更加容易实现类的扩展.子类是父类的扩展 使用extends实现继承 package cn.sxt;public class Test {pu ...

  2. python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)

    面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...

  3. php对象的三大特征,关于php中面向对象的三大特征(封装/继承/多态)

    最近在学习php的过程中发现它其实比java的语言要松散很多,而且很多人说上手比较容易,但是智言我个人并不是很认同这样的观点,因为其实java的整个语法规则都非常的有条有理,虽然函数很多,但是至少经常 ...

  4. 面向对象编程三大特征之一 继承

    文章目录 继承 概述 语句定义格式 继承的特点 注意事项 继承与成员变量之间的关系 this关键字与super关键字的使用区别 继承与构造方法的关系 继承与成员方法的关系 重写与重载的区别 方法重写的 ...

  5. Python攻城师的成长————面向对象的三大特征(继承、多态)

    学习目标: 了解继承与多态的概念,重点是要学会运用继承去处理问题 学习内容: 继承 在面对对象程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类,而被继 ...

  6. 面向对象的三大特征之一继承

    继承的理解 一 1.继承是单继承,继承一个父类 2.判断子类与父类的关系:is-a(狗是一个宠物) 3.用关键词extends 4子类可以调用父类的方法(注有权限问题) 二 子类访问父类的成员 1访问 ...

  7. Python学习笔记④——类、面向对象的三大特征 [封装+继承+多态]

    ✅ Blogger Learns Python is for learning the "Deep Learning". 文章目录 一.面向对象编程的简介 二.类与对象 -- 基础 ...

  8. OC面向对象的三大特征(封装 继承 多态)习题2 复合

    复合:一个类中有一个成员变量是另外一个类的对象. 比如我现在要制作一台电脑,电脑需要CPU,显示器,鼠标和键盘等.这些东西的研发都是很复杂的过程.如果现在有成型的CPU等组件,就可以直接用这些组件攒一 ...

  9. Java中面向对象三大特征总结

    JAVA中面向对象的三大特征: 面向对象具有继承性(Inheritance) 面向对象具有多态性(Polymorphism) 面向对象具有封装性(Encapsulation) 一.继承 多个类具有共同 ...

最新文章

  1. 哪些人适合学习java技术
  2. java big o_java – 计算Big-O复杂性
  3. 沉浸式技术immersive technology
  4. SpringBoot中整合Mail实现发送模板邮件
  5. LSA(链路状态通告)类型
  6. 一、HTML和CSS基础--HTML+CSS基础课程--第1部分
  7. 坚持己见还是随波逐流
  8. C# VS2017 winForm 使tableLayoutPanel 不闪烁
  9. 设计模式:装饰模式(C++)【小明习武闯天下】
  10. 速修复!这个严重的 Apache Struts RCE 漏洞补丁不完整
  11. Camtasia混音教程
  12. 为什么材料专业要劝退?材料专业就找不到好工作吗?
  13. JavaScript hash 与 history 实现客户端路由的原理
  14. Launcher 记录自定义桌面
  15. excel怎么启用宏_怎么使用Excel制作条形码?操作如此简单
  16. 锐捷(三)清除交换机的虚拟化(VSU)配置
  17. 幸运数的定义及其判断
  18. 三坐标检测基础知识之建立工件坐标系
  19. 智能优化算法--灰狼算法
  20. excel 的操作 http://wwwb.pconline.com.cn/pcedu/soft/excel.html

热门文章

  1. 分治法之图解最大子序列和
  2. 电脑能正常上网,但是不能连接共享的打印机 电脑无法打印 服务打开无法打印
  3. 10-219 通过订单表和顾客表,查询订单编号,顾客编号,公司 名称和订单日期
  4. Error: No such container:path: 630f5b9a1a00d26975cd4fda3464af0829bbfb1f21c1e30238fec7c11eed609d:/var
  5. mysql多张表join_SQL优化之多表join
  6. R语言入门第二集 实验一:R 语言数据结构、数据导入与数据处理
  7. python中replace()方法
  8. mac版phpstorm中文切换为英文
  9. python大作业有哪些项目 选题做个啥【推荐】
  10. win10改计算机用户名,简单几步解决win10电脑用户名改不了的问题