java中继承:1.super关键字;2.override

继承
1.1    类和类之间的常见关系。
    1 :既然继承是描述类和类之间的关系,就需要先来了解类和类之间的常见关系
1.1.1    现实生活的整体与部分
举例说明
1 :现实生活
    1 :学生    是人  
    2 :狗      是动物
    3 :球队 包含 球员 整体与部分的关系,部分可以删除和增加
    4 :笔记本包含 cpu 整体与部分的关系,部分不可以删除和增加
    5 :航母编队 包含(航母 护卫舰 驱逐舰 舰载机 核潜艇)
1.1.2    java 中的类与类关系
java 中的类关系
1 is a 关系 ( 学生是人 )
2 has a 整体与部分
class Person {
    String name ;
    int age ;
    Address add ;
   
    Person(){
      
    }
    Person(String name, int age,Address add){
      
       this . name =name;
       this . age =age;
       this . add =add;
      
    }
   
    void speak(){
       System. out .println( " 姓名: " + name + " 年龄: " + age + " " + add .print());
    }
}
class Address{
    String country ;
    String city ;
    String street ;
   
    Address(){
   
    }
    Address(String country,String city,String street){
       this . country =country;
       this . city =city;
       this . street =street;
    }
   
    String print(){
       return " 地址: " + country + " " + " 城市: " + city + 街道; " + street ;
    }
}
class Demo3{
 
    public static void main(String[] args){
      
       Address add= new Address( " 中国 " , " 广州 " , " 棠东东路 " );
       Person p= new Person( "jack" ,27,add);
       p.speak();
      
      
       System. out .println();
        }
}
   
 
1.2    继承
    1 :描述一个学生类
       1 :姓名年龄学号属性,学习的方法
    2 :描述一个工人类
       1 :姓名年龄工号属性,工作的方法
    3 :描述一个人类
       1 :姓名年龄属性,说话的方法。
4 :发现学生类和人类天生有着联系,学生和工人都是人。所以人有的属性和行为学生和工人都会有。出现类代码重复
class Person {
    String name ;
    int age ;
 
    // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
    static String country = "CN" ;
 
    Person() {
 
    }
 
    void speak() {
       System. out .println( name + ": 哈哈,我是人!!! " );
    }
 
}
 
// 让学生类和人类产生关系,发现学生 is a 人,就可以使用继承
class Student {
 
    String name ;
    int age ;
 
    Student() {
 
    }
 
    void study() {
       System. out .println( " 姓名: " + name + " 年纪: " + age + ": 好好学习 " );
    }
}
 
class Worker {
    String name ;
    int age ;
 
    void work() {
       System. out .println( name + ": 好好工作,好好挣钱。 " );
    }
 
}
 
class Demo1 {
 
    public static void main(String[] args) {
       Student s = new Student();
       s. name = "jack" ;
       s. age = 20;
       s.study();
 
       Worker w = new Worker();
       w. name = "rose" ;
 
       w.work();
    }
}
 
    5 :问题 :
       1 :如果没有继承 , 出现类和类的关系无法描述
       2 :如果没有继承,类和类之间有关系会出现类和类的描述代码的重复。
1.3    继承特点
    1 :描述类和类之间的关系
    2 :降低类和类之间的重复代码
1 :降低对象和对象之间的代码重复使用静态变量
    2 :降低类和类之间的代码重复使用就继承
   
1.4    extends 关键字
继承使用 extends 关键字实现
1 :发现学生是人,工人是人。显然属于 is a 的关系, is a 就是继承。
2 :谁继承谁?
    学生继承人,发现学生里的成员变量,姓名和年龄,人里边也都进行了定义。有重     复代码将学生类的重复代码注释掉,创建学生类对象,仍然可以获取到注释的成员。这就是因为继承的关系,学生类(子类)继承了人类(父类)的部分
class Person {
    String name ;
    int age ;
 
    // 静态变量(类变量)对象和对象之间的代码重复使用静态变量
    static String country = "CN" ;
 
    Person() {
 
    }
 
    void speak() {
       System. out .println( name + ": 哈哈,我是人!!! " );
    }
 
}
 
// 让学生类和人类产生关系,发现学生 is a 人,就可以使用继承
class Student extends Person {
 
    Student() {
 
    }
 
    void study() {
       System. out .println( " 姓名: " + name + " 年纪: " + age + ": 好好学习 " );
    }
}
 
class Worker extends Person {
 
    void work() {
       System. out .println( name + ": 好好工作,好好挣钱。 " );
    }
 
}
 
class Demo1 {
 
    public static void main(String[] args) {
       Student stu = new Student();
       stu. name = "jack" ;
       stu. age = 20;
       stu.study();
        stu.speak();
       System. out .println(stu. country );
       System. out .println(Student. country );
 
       Worker worker = new Worker();
       worker. name = "rose" ;
       System. out .println(worker. country );
       worker.work();
       worker.speak();
 
       System. out .println();
    }
}
 
继承细节;       
    1 :类名的设定,被继承的类称之为父类 ( 基类 ) ,继承的类称之为子类
    2 :子类并不能继承父类中所有的成员
1 :父类定义完整的成员 静态成员,非静态,构造方法。静态变量和静态方
法都可以通过子类名 . 父类静态成员的形式调用成功。
       2 所有的私有成员不能继承 ,private 修饰的成员。
       3 构造函数不能被继承
 
    3 :如何使用继承
1 :不要为了使用继承而继承。工人和学生都有共性的成员,不要为了节省代
码,让工人继承学生。
/*
如何使用继承:验证是否有 is  a 的关系
  例如:学生是人, 小狗是动物
  注意:不要为了使用某些功能而继承 ,java 只支持单继承
 */
class DK {
 
    void Ip4S() {
       System. out .println( " 好玩 " );
    }
}
 
class BGir extends DK {
 
}
 
class Demo {
 
    public static void main(String[] args) {
 
       new BGir().Ip4S();
 
    }
}
 
1.5 super 关键字
    1 :定义 Father( 父类 )
       1 :成员变量 int x=1;
       2 :构造方法无参的和有参的,有输出语句
    2 :定义 Son extends Father
       1 :成员变量 int y=1;
       2 :构造方法无参和有参的。有输出语句
       1 this.y=y+x;
    3 :创建 Son 类对象
       Son son=new Son(3);
       System.out.println(son.y); //4
class Father {
    int x = 1;
 
    Father() {
       System. out .println( " 这是父类无参构造 " );
    }
 
    Father( int x) {
 
       this . x = x;
       System. out .println( " 这是父类有参构造 " );
    }
 
    void speak() {
       System. out .println( " 我是父亲 " );
    }                 
}
 
class Son extends Father {
    int y = 1;
 
    Son() {
       System. out .println( " 这是子类的无参构造 " );
    }
 
    Son( int y) {
 
       this . y = y + x ;
       System. out .println( " 这是子类的有参构造 " );
    }
 
    void run() {
       super .speak(); // 访问父类的函数
       System. out .println( " 我是儿子 " );
    }
}
 
class Demo6 {
 
    public static void main(String[] args) {
       Son s = new Son(3);
       System. out .println(s. y ); // 4
    }
}
 
    4 :子类对象为什么可以访问父类的成员。
       1 this.y=y+x; 有一个隐式的 super super.x
 
    5 super 关键字作用
       1 :主要存在于子类方法中,用于指向子类对象中父类对象。
       2 :访问父类的属性
       3 :访问父类的函数
       4 :访问父类的构造函数
    6 super 注意

super关键字调用父类构造方法要注意的事项:
1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。
2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的 第一个语句
3. super与this关键字不能同时出现在同一个构造函数中 调用其他的构造函数 。因为两个语句都需要第一个语句。(this.name = name可以)


this super 很像, this 指向的是当前对象的调用, super 指向的是当前调用对象的父类。 Demo 类被加载,执行 main 方法, Son.class 加载,发现有父类 Father 类,于是 Father 类也加载进内存。类加载完毕,创建对象,父类的构造方法会被调用(默认自动无参),然后执行子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部。 this super 只能在有对象的前提下使用,不能在静态上下文使用。
2 :子类的构造函数默认第一行会默认调用父类无参的构造函数,隐式语句
super();
           1 :父类无参构造函数不存在,编译报错。
  
Son( int y) {
       //super(); 隐式语句
       this . y = y + x ;
       System. out .println( " 这是子类的有参构造 " );
    }
 
    3 :子类显式调用父类构造函数
在子类构造函数第一行通过 super 关键字调用父类任何构造函数。如果显式调用父类构造函数,编译器自动添加的调用父类无参数的构造就消失。构造函数间的调用只能放在第一行,只能调用一次。 super() this() 不能同时存在构造函数第一行。
Son( int y ) {
       super ( y );// 子类显式调用父类构造函数
       this . y = y + x ;
       System. out .println( " 这是子类的有参构造 " );
    }
 
Son( int y) {
       this ();  // 不能同时存在构造函数第一行  
       super (y);
       this . y = y + x ;
       System. out .println( " 这是子类的有参构造 " );
    }
 
    4 super 思考
如果开发者自定义了一个类,没有显示的进行类的继承,那么该类中成员函数是否可以使用 super 关健健字?可以使用,继承了 Object 类, Object 类是所有类的父类。
class Demo7 {
    public   void print(){
       System. out .println( super .toString());
    }
    public static void main(String[] args){
       new Demo7().print();
       System. out .println();
        }
}
 
    5 :继承练习
   
重写( Override

方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。

什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。

1 :定义 Father
    1 :姓名,吃饭方法,吃窝窝头。
    2 :定义 Son 类,继承 Father
       1 Son 类中不定义任何成员,子类创建对象,仍然可以调用吃饭的方法。
       2 :父类的吃饭的方法, Son 不愿吃。 Son 自己定义了吃饭的方法。
1 :此时父类中有一个吃饭的方法,子类中有 2 个吃饭的方法,一模一样,只是方法体不一样。
           2 :一个类中两个函数一模一样,是不允许的。
              1 :编译运行,执行了子类的方法。
              2 :使用父类的方法,在子类方法中,使用 super. 父类方法名。
class Father {
    String name ;
 
    void eat() {
       System. out .println( " 吃窝窝 " );
    }
}
 
class Son extends Father {
 
    public void eat() { // 继承可以使得子类增强父类的方法
       System.out.println(" 来俩小菜 ");
       System.out.println(" 来两杯 ");
       System.out.println(" 吃香喝辣 ");
           System. out .println( " 来一根 " );
    }
}
 
class Demo8 {
 
    public static void main(String[] args) {
       Son s = new Son();
        // 执行子类的方法
       s.eat();
 
    }
}
 
3 :该现象就叫做重写 ( 覆盖 override)
1 在继承中,子类可以定义和父类相同的名称且参数列表一致的函数,将这种函数
称之为函数的重写 .
4 :前提
    1 :必须要有继承关系
5 :特点
1 :当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数。
       可以通过 super 关键字进行父类的重写函数的调用。
    2 继承可以使得子类增强父类的方法
6 :细节
    1 函数名必须相同
    2 :参数列表必须相同
3 子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访
问权限否则编译报错
4 :子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类。不能返回比父类更大的数据类型: 如子类函数返回值类型是 Object
 
       1 :定义 A B  C B extends A 
       2 Father 类中定义 A getA();
       3 Son 类中重写 getA(); 方法,尝试将返回值修改为 B C ,Object
           1 B 编译通过
           2 C 编译失败 , 没有继承关系
           3 Object 编译失败 , 比父类的返回值类型更大
class A {
 
}
 
class B extends A {
 
}
 
class C {
 
}
class Father {
    String name ;
 
    void eat() {
       System. out .println( " 吃窝窝 " );
    }
 
    // 定义一个函数,获取 A 类的对象,
    A getA() {
       return new A();
    }
 
}
 
class Son extends Father {
 
    public void eat() { // 继承可以使得子类增强父类的方法
       System. out .println( " 来两杯 " );
       System. out .println( " 来俩小菜 " );
       super .eat();
       System. out .println( " 来一根 " );
    }
 
    // B 类是 A 类的子类
    B getA() {
       return new B();
    }
}
 
class Demo8 {
 
    public static void main(String[] args) {
       Son s = new Son();
       s.eat();
 
    }
}
 
7 :子类对象查找属性或方法时的顺序:
    1 :原则:就近原则。
如果子类的对象调用方法,默认先使用 this 进行查找,如果当前对象没有找到属性或方法,找当前对象中维护的 super 关键字指向的对象,如果还没有找到编译报错,找到直接调用。
8 重载和重写的不同
    方法重写要注意的事项:
1.方法重写时, 方法名与形参列表必须一致。
2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。
3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。
4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。
Exception(最坏)
RuntimeException(小坏)

方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。

方法重载的要求
1. 函数名要一致。
2. 形参列表不一致(形参的个数或形参 的类型不一致)
3. 与返回值类型无关。
9 :重写练习
       描述不同的动物不同的叫法
       1 :定义动物类
           有名字,有吃和叫的方法
       2 :定义狗继承动物重写父类吃和叫的方法
       3 :定义猫继承动物重写父类吃和叫的方法
class Animal{
    int x =1;
    String name ;
   
    void eat(){
       System. out .println( " 吃东西 " );
    }
    void shout(){
       System. out .println( " 我是动物 " );
    }
}
 
class Dog extends Animal{
   
   
    void eat(){
       System. out .println( " 啃骨头 " );
    }
    void shout(){
       System. out .println( " 旺旺 " );
    }
    void eat(String food){
       System. out .println( " 吃: " +food);
    }
}
class Cat extends Animal{
 
    void eat(){
       System. out .println( " 吃老鼠 " );
    }
    void shout(){
       System. out .println( " 喵喵 " );
    }
}
 
class Demo9{
 
    public static void main(String[] args){
       Dog d= new Dog();
       d.shout();
       d.eat();
      
       Cat c= new Cat();
       c.shout();
       c.eat();
       System. out .println();
        }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值