java的继承

继承

java可以使用extends关键字,可以让一个类和另一个类建立父子关系。

特点:子类可以继承父类的非私有成员(成员变量,成员方法)

子类的对象是由子类和父类共同创建的

使用:

定义了一个父类:

cpp 复制代码
public class people {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

定义的子类:

cpp 复制代码
public class teacher extends people {
    private String skill;

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
    public void printname()
    {
        System.out.println(getName()+"的技能有"+getSkill());//可以直接访问父类的成员方法
    }
}

使用:

cpp 复制代码
public class test {
    public static void main(String[] args) {
        teacher t1=new teacher();
        t1.setName("hh");
        t1.setSkill("java");
        t1.printname();//hh的技能有java
    }

}

可以看出子类创建出的对象可以使用父类和子类的成员方法。

权限修饰符

概念:就是用来限制类中的成员能够被访问的范围

|-----------|------|-----------|-------------|---------|
| 修饰符 | 在本类中 | 同一个包下的其他类 | 任意包下的子类 | 任意包的任意类 |
| private | y | | | |
| 缺省 | y | y | | |
| protected | y | y | y | |
| public | y | y | y | y |

操作:

cpp 复制代码
public class fu {
    public void publicmethod()
    {
        System.out.println("public");
    }
    protected  void protectedmethod()
    {
        System.out.println("protected");
    }
    private void privatemethod()
    {
        System.out.println("private");
    }
    void method()
    {
        System.out.println("缺省");
    }
    public void test()
    {
        publicmethod();
        privatemethod();
        protectedmethod();
        method();
    }
}
cpp 复制代码
public class test {
    public static void main(String[] args) {
        fu f1=new fu();
        f1.test();
       /* public
        private
        protected
        缺省*/
    }
}

可以发现在本类中可以访问四种类型的权限修饰符

cpp 复制代码
public class test {
    public static void main(String[] args) {
        fu f1=new fu();
        f1.test();
       /* public
        private
        protected
        缺省*/
        f1.method();
        f1.publicmethod();
        f1.protectedmethod();
    }
}

也可以发现可以在同一个包下的其他类可以访问除了private的其余三种权限修饰符修饰的成员

cpp 复制代码
public class zi extends fu{
    public void test()
    {
        protectedmethod();
        publicmethod();
    }
}

在任意包下的子类可以访问protected和public修饰的成员。

cpp 复制代码
import com.he.extern2.fu;

public class test {
    public static void main(String[] args) {
        /*teacher t1=new teacher();
        t1.setName("hh");
        t1.setSkill("java");
        t1.printname();//hh的技能有java*/
        fu f1=new fu();
        f1.publicmethod();
    }

}

在其他包的任意类下可以访问public修饰的成员

cpp 复制代码
public class test {
    public static void main(String[] args) {
        /*teacher t1=new teacher();
        t1.setName("hh");
        t1.setSkill("java");
        t1.printname();//hh的技能有java*/
        fu f1=new fu();
        f1.publicmethod();
        zi z1=new zi();
        //zi.protectedmethod();//'protectedmethod()' has protected access in 'com.he.extern2.fu'
    }

}

可见只能在子类下才能访问protected修饰的成员,子类的对象不行

单继承:

java是单继承的,一个类只能继承一个直接父类,但是可以多层继承;

object类是java所有类的祖宗

方法重写:

当子类觉得父类的某个方法不好用,子类可以重新写一个方法名称,参数列表一样的方法,去覆盖父类的这个方法。

注意:重写后,方法的访问,java会遵循就近原则

例如:重写父类的print方法

cpp 复制代码
public class zi extends fu{
    @Override//提示方法重写,写错名字就报错
    public void print()
    {
        System.out.println("777");
    }
}
  1. 子类重写父类方法时,访问权限必须大于或等于父类该方法的权限(public>protected>缺省)
  2. 重写的方法的返回值类型 ,必须与被重写方法的返回值类型一样,或者范围更小
  3. 私有方法,静态方法不能被重写
  4. @Override

重写object类的toString()方法:

cpp 复制代码
public class student {
   private String name;
   int age;

    public student() {
    }

    public student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

object类的toString返回的是对象的地址
打印默认是调用了对象的toString方法

cpp 复制代码
public class test {
    public static void main(String[] args) {
        student s1=new student("hh",18);
        System.out.println(s1.toString());//com.he.extern4.student@2f4d3709
        //object类的toString返回的是对象的地址
        //打印默认是调用了对象的toString方法
        System.out.println(s1);//com.he.extern4.student@2f4d3709
        System.out.println(s1.getName());

    }
}

重写toString()方法后:

student{name='hh', age=18}

student{name='hh', age=18}

子类访问其他成员的方法:就近原则

父类:

cpp 复制代码
public class father {
    String name="父类";
    public void method()
    {
        System.out.println("父类--method");
    }
}

子类:

cpp 复制代码
public class son extends father{
    String name="子类";
    public void printname()
    {
        String name="局部";
        System.out.println(name);//局部变量
        System.out.println(this.name);//子类成员变量
        System.out.println(super.name);//父类成员变量
    }
    @Override
    public void method()
    {
        System.out.println("子类---method");
    }
    public void showmethod()
    {
        method();//子类本身成员方法
        super.method();//父类成员方法
    }
}

子类构造器的特点:

子类的全部构造器,都会先调用父类的构造器,再执行自己的构造器

默认调用父类的无参构造器

cpp 复制代码
class fa{
    private int age;
    public fa()
    {
        System.out.println("父类无参构造器");
    }
}
class so extends fa
{
    private int age;
    public so()
    {
        //super();//默认
        System.out.println("子类无参构造器");
    }
    public so(int age)
    {
        //super();//默认
        System.out.println("子类有参构造器");
    }
}
public class test1 {
    public static void main(String[] args) {


        so s1 = new so();
        so s2 = new so(3);
    }
}

结果:

复制代码
父类无参构造器
子类无参构造器
父类无参构造器
子类有参构造器

如果父类没有无参构造器怎么办

cpp 复制代码
class fa{
    private int age;
    public fa(int age)
    {
        System.out.println("子类有参构造器");
    }
}
class so extends fa
{
    private int age;
    public so()
    {
        //super();//默认
        super(3);
        System.out.println("子类无参构造器");
    }
    public so(int age)
    {
        //super();//默认
        super(4);
        System.out.println("子类有参构造器");
    }
}
public class test1 {
    public static void main(String[] args) {


        so s1 = new so();
        so s2 = new so(3);
    }
}

解决方法:在子类自己写一个父类有参构造器

在子类中先调用父类构造器的好处:

父类:

cpp 复制代码
public class father {
    private String name;
    private int age;

    public father() {
    }

    public father(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }
}

子类:

由于name,age是父类的成员变量,不能使用this,所以用super(),调用父类的有参构造器
super(name,age);

cpp 复制代码
public class son extends father{
    private String skill;

    public son() {
    }

    public son(String name,int age,String skill)
    {
//由于name,age是父类的成员变量,不能使用this,所以用super(),调用父类的有参构造器
        super(name,age);
        this.skill=skill;
    }
    public son(String skill) {
        this.skill = skill;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

测试:

cpp 复制代码
public class test {
    public static void main(String[] args) {
        son s1=new son("nnn",18,"java");
        System.out.println(s1.getName());
        System.out.println(s1.getAge());
        System.out.println(s1.getSkill());
    }
}

this(...)可以调用兄弟构造器

注意:this(...)和super()都要写到第一行,所以不能同时写

cpp 复制代码
public class test {
    public static void main(String[] args) {
        student s1=new student("hh",45);
 //假如用户没有输入age,默认age18
        student s2=new student("aa");
        System.out.println(s2.getName());//aa
        System.out.println(s2.getAge());//18
       
    }
}
class student
{
    private String name;
    private int age;

    public student() {
    }
    public student(String name)
    {
        this(name,18);//调用下面的有参兄弟构造器,自己把18传进去
    }
    public student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

总结:

super(...)为对象包含父类这部分的成员变量进行赋值

this(...)在构造器中调用本类的其他构造器

相关推荐
五味香15 分钟前
C++学习,信号处理
android·c语言·开发语言·c++·学习·算法·信号处理
无理 Java19 分钟前
【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
java·后端·spring·面试·mvc·框架·springmvc
梓䈑31 分钟前
【C语言】自定义类型:结构体
c语言·开发语言·windows
..空空的人1 小时前
linux基础指令的认识
linux·运维·服务器
penny_tcf1 小时前
Linux基础命令halt详解
linux·运维·服务器
gobeyye1 小时前
spring loC&DI 详解
java·spring·rpc
鱼跃鹰飞1 小时前
Leecode热题100-295.数据流中的中位数
java·服务器·开发语言·前端·算法·leetcode·面试
我是浮夸1 小时前
MyBatisPlus——学习笔记
java·spring boot·mybatis
小蜗笔记1 小时前
在Python中实现多目标优化问题(7)模拟退火算法的调用
开发语言·python·模拟退火算法