简单理解继承:继承分为父类和子类,子类继承父类,子类可以使用父类中public(公有的) 的成员属性和成员方法,但是子类中也可以有属于自己的成员变量和成员方法,但是父类不可以调用子类中的属性和方法
具体场景:鸟类 (父类)一个抽象的概念,鸟可以有自己的(属性)姓名,基本功能(方法)是吃饭,睡觉
================================================
鹰类(子类),鹰类继承鸟类,鹰类可以调用鸟类里面的(属性)姓名,也可以继承里面的(方法)基本功能,吃饭,睡觉,但是鹰类有个自己的专属功能就是飞行(举个例子,大部分鸟都会飞)
================================================
鸵鸟类(子类),鸵鸟类继承鸟类,和上面类似,继承基础的属性和功能都具备,鸵鸟类自己的专属技能就是奔跑(找到一个不会飞的鸟,差异化)
以上对继承的简单理解
父类
public class fu{
//属性(成员变量)
//功能(成员方法)
}
子类–继承上面父类
public class zi extends fu{
//属性(成员变量)
//功能(成员方法)
}
例子:
定义一个鸟类(父类)
/**
* @Classname : bird
* @Description : TODO 鸟类 - 父类
* @Author : [email protected]
*/
public class bird {
//两个成员变量
public String name; //姓名
public int age; // 年龄
//无参数的构造方法
public bird() {
}
//两个参数的构造方法
public bird(String name, int age) {
this.name = name;
this.age = age;
}
//两个成员方法
public void eat(){
System.out.println(this.name+"基本功能:会吃");
}
public void sleep(){
System.out.println(this.name+"基本功能:会睡觉");
}
}
定义一个鹰类(子类),继承鸟类
/**
* @Classname : hawk
* @Description : TODO 鹰类 - 继承鸟类
* @Author : [email protected]
*/
public class hawk extends bird {
//定义一个成员变量
public int altitude;//飞行高度
//无参数的构造方法
public hawk() {
}
//三个带参数的构造方法
public hawk(String name, int age, int altitude) {
//super是调用父类当中的构造方法
super(name, age);
this.altitude = altitude;
}
//鹰类的功能飞行
public void fly() {
System.out.println(this.name + "," + this.age + "岁" + "可以飞行");
System.out.println("飞行高度" + this.altitude + "米");
}
}
测试类,实例子化调用上面类
/**
* @Classname : test
* @Description : TODO 测试类
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化bird
bird bird = new bird("鸟",3);
bird.eat();
bird.sleep();
System.out.println("===================");
//实例化hawk类
hawk hawk = new hawk("鹰",1,9000);
//调用继承的方法
hawk.eat();
hawk.sleep();
hawk.fly();
}
}
鹰类当中没定义姓名(name)和年龄(age)的成员变量,也没有定义eat和sleep方法,但是鹰类继承了鸟类,可以进行调用
运行结果;
两个关键字
super:带有super关键字修饰的方法和变量代表是父类的中的功能和属性
this:代表是自己类中的,封装笔记里面也有记录
局部变量:没有修饰符应该就是局部变量或者形式参数了
例子
定义一个父类
/**
* @Classname : fu
* @Description : TODO 父类
* @Author : [email protected]
*/
public class fu {
//定义两个成员变量
public String name;
public int age;
//定义无参的构造方法
public fu() {
}
//定义两个带参数的构造方法
public fu(String name, int age) {
this.name = name;
this.age = age;
}
//定义一个成员方法
public void eat(){
System.out.println(this.age + "岁的" + this.name + "正在吃");
}
}
定义一个子类-继承上面父类
/**
* @Classname : zi
* @Description : TODO 子类 - 继承fu类
* @Author : [email protected]
*/
public class zi extends fu {
//定义两个和fu类名字相同的属性
public String name;
public int age;
//定义无参数的构造方法
public zi() {
}
//定义四个带参数的构造方法
/**
* 成员变量初始化的构造方法
*
* @param name 父类中name初始化
* @param age 父类中age初始化
* @param name1 子类中name进行初始化
* @param age1 子类中age进行初始化
*/
public zi(String name, int age, String name1, int age1) {
super(name, age);//调用父类中两个参数的构造方法
this.name = name1;
this.age = age1;
}
public void eat() {
//子类中调用父类中同名的成员变量的方式 super.变量名字
System.out.println(super.age + "岁的" + super.name + "正在吃");
//调用自己类里面的成员变量this.变量名
System.out.println(this.age + "岁的" + this.name + "正在吃");
}
}
super();
,是调用父类中构造方法,例如下面的代码,就是调用父类中带有两个参数的构造方法
super(name,age);//调用父类中带有两个参数的构造方法
测试类
/**
* @Classname : test
* @Description : TODO 测试类
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化fu类对象
fu fu = new fu("黄固",35);
fu.eat();
System.out.println("=============");
//实例化zi类对象
zi zi = new zi("黄固",35,"黄蓉",12);
zi.eat();
}
}
运行结果:
通过super关键字和this关键字能清晰知道成员变量是属于父类还是子类,具体调用过程查看zi类里面eat方法中的注释
方法重写:简单来说就是父类和子类中有一个名字返回值类型相同的方法,但是子类中和父类中输出内容不一样
例子:
定义一个父类
/**
* @Classname : Fu
* @Description : TODO - 父类
* @Author : [email protected]
*/
public class Fu {
//定义两个成员变量
public String name; //姓名
public int age; // 年龄
//定义无参构造方法
public Fu() {
}
//定义带两个参数的构造方法
/**
* 初始化两个成员变量
* @param name 姓名
* @param age 年龄
*/
public Fu(String name, int age) {
this.name = name;
this.age = age;
}
//定义一个eat方法
public void eat(){
System.out.println(this.age + "岁的" + this.name + "吃面条");
}
}
定义一个子类-继承父类
/**
* @Classname : zi
* @Description : TODO 子类 - 继承Fu类
* @Author : [email protected]
*/
public class zi extends Fu {
//定义两个和Fu类相同的成员变量
public String name;
public int age;
//定义无参构造方法
public zi() {
}
/**
* 四个参数的构造方法,给Fu类和zi类 成员属性初始化
*
* @param name Fu类name赋值
* @param age Fu类age赋值
* @param name1 zi类name赋值
* @param age1 zi类age赋值
*/
public zi(String name, int age, String name1, int age1) {
super(name, age);
this.name = name1;
this.age = age1;
}
//重写Fu类里面的eat方法
public void eat() {
System.out.println(this.age + "岁的女儿" + this.name + "吃米饭");
}
//调用子类和父类中eat方法的方式
public void show(){
//调用zi类中重写的eat方法 this.方法名字
this.eat();
System.out.println("================");
//直接调用Fu类中的eat方法 super.方法名
super.eat();
}
}
测试类
/**
* @Classname : test
* @Description : TODO - 测试类
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化Fu类
Fu fu = new Fu("黄固",32);
fu.eat();
System.out.println("====================");
//实例化子类
zi zi = new zi("黄固",33,"黄蓉",12);
zi.eat();
System.out.println("=====================");
zi.show();
}
}
总结:
- Fu类中eat和zi类中eat两种输出的内容不同,Fu类eat吃面条,zi类eat输出吃米饭,这大概就是zi类对Fu类的eat方法进行重写吧
- 子类中调用本类中eat方法和调用Fu类中eat方法的方式,参考zi类中show方法注释
修饰符 | 类内部 | 同包内 | 子类内 | 其他中 |
---|---|---|---|---|
private |
YES | NO | NO | NO |
default |
YES | YES | NO | NO |
protected |
YES | YES | YES | NO |
public |
YES | YES | YES | YES |
带有上面修饰符的成员变量和方法有些地方不能调用
例子:定义一个Fu类,
package com.xs.demo04;
存放这个包里面,定义出几个上面修饰符成员变量
package com.xs.demo04;
/**
* @Classname : Fu
* @Description : TODO
* @Author : [email protected]
*/
public class Fu {
//定义四个不同修饰符的成员变量
public String varpub = "我是公有变量";
private String varpri = "我是私有变量";
protected String varpro = "我是受保护的";
String vardef = "我是默认的";
}
测试类:同一个包里面可以调用上面父类那些修饰符成成员变量
package com.xs.demo04;//完整的包路径.类名
/**
* @Classname : test
* @Description : TODO
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化对象
Fu fu = new Fu();
System.out.println(fu.vardef);
System.out.println(fu.varpro);
System.out.println(fu.varpub);
//同一个包里面,除了私有变量,其他都能进行访问
System.out.println("=========================");
}
}
例子:定义一个子类继承上面Fu类
package com.xs.demo04;
/**
* @Classname : zi
* @Description : TODO
* @Author : [email protected]
*/
public class zi extends Fu{
//定义一个成员方法
public void show(){
//输出Fu类中可以访问的成员变量
System.out.println(super.vardef);
System.out.println(super.varpro);
System.out.println(super.varpub);
//同包子类中,除了private修饰的变量,其他都可以访问到
}
}
测试类,测试输出结果
package com.xs.demo04;
/**
* @Classname : test
* @Description : TODO
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化对象
zi zi = new zi();
zi.show();
System.out.println("=========================");
}
}
例子:
package com.xs.demo05;
import com.xs.demo04.Fu;//导入Fu类的包路径和继承的类名
/**
* @Classname : Zi02
* @Description : TODO -子类02 继承 demo04里面的Fu类
* @Author : [email protected]
*/
public class Zi02 extends Fu {
public void show(){
System.out.println(super.varpro);
System.out.println(super.varpub);
//不同包里的子类,继承其他包里面的父类能访问的只有,public 和 default(默认的类)
}
}
调用上面的类
package com.xs.demo05;
/**
* @Classname : test
* @Description : TODO
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化Zi02类
Zi02 zi02 = new Zi02();
zi02.show();
}
}
没事,理解下面的四点在去看看?
总结四点
- 同类中四种权限符修饰的成员变量都可以进行访问,private是不能直接进行访问的,除了类里面任何地方都不行哦~
- public哪里都可以进行访问
- 默认的(default),只有同类同一个包里面可以进行访问,子类继承的也可以访问
- protected是同包里面子类继承或者不同包里面子类继承时才能进行访问,其他包里面子类没有继承不能访问
this();
,是调用类中构造方法,根据括号里的参数调用类中那个构造方法
例子:定义一个人类(Person)
package com.xs.demo06;
/**
* @Classname : Person
* @Description : TODO - 人类
* @Author : [email protected]
*/
public class Person {
//定义四个人类基本属性
private String name; //姓名
private int age;//年龄
private String sex;//性别
private String jop;//职业
//无参数的构造方法
public Person() {
System.out.println("无参数的构造方法");
}
//带一个参数的构造方法
public Person(String name){
this();//调用上面无参数构造方法
this.name = name;
}
//带2个参数的构造方法
public Person(String name,int age){
this(name);//调用上面一个参数的构造方法
this.age = age;
}
//带3个参数的构造方法
public Person(String name,int age,String sex){
this(name,age);//调用上面2个参数的构造方法
this.sex = sex;
}
//带四个参数的构造方法
public Person(String name,int age,String sex,String jop){
this(name,age,sex);//调用上面3个参数的构造方法
this.jop = jop;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", jop='" + jop + '\'' +
'}';
}
}
注意注释
测试结果类
package com.xs.demo06;
/**
* @Classname : test
* @Description : TODO 测试类
* @Author : [email protected]
*/
public class test {
public static void main(String[] args) {
//实例化对象Person
Person person = new Person("小肆",18,"女","学生");
System.out.println(person);
}
}
调用Person类当中四个参数的构造方法,然后套娃式进行调用,直到调用无参数构造方法,上面代码应该可以帮助你理解this.,调用类中构造方法的方式
运行结果: