1.Extands
package com.gdledu.extend_;
//大学生-> 模拟大学生考试的简单情况
public class Gruduate {
public String name;
public int age;
private double score;
public void setScore(double score) {
this.score = score;
}
public void testing(){
System.out.println(name + "正在考英语四级");
}
public void showInfo(){
System.out.println(name + " 年龄 " + age + " 成绩 " + score);
}
}
package com.gdledu.extend_;
//小学生->模拟小学生考试情况
public class Pupil {
public String name;
public int age;
private double score;
public void setScore(double score) {
this.score = score;
}
public void testing(){
System.out.println(name + "正在考英文");
}
public void showInfo(){
System.out.println(name + " 年龄 " + age + " 成绩 " + score);
}
}
//相同属性多,复用性差,引出继承
package com.gdledu.extend_.improve_;
//父类,是pupil和graduate的父类
public class Student {
//共有属性
public String name;
public int age;
private double score;
//共有方法
public void setScore(double score) {
this.score = score;
}
public void showInfo(){
System.out.println(name + " 年龄 " + age + " 成绩 " + score);
}
}
package com.gdledu.extend_.improve_;
//让Pupil继承Student
public class Pupil extends Student{
public void testing(){
System.out.println(name + "正在考英语四级");
}
}
package com.gdledu.extend_.improve_;
//让Graduate继承Student
public class Graduate extends Student{
public void testing(){
System.out.println(name + "正在考英语四级");
}
}
package com.gdledu.extend_.improve_;
import com.gdledu.extend_.Gruduate;
import com.gdledu.extend_.Pupil;
public class Extends01 {
public static void main(String[] args) {
com.gdledu.extend_.Pupil pupil = new Pupil();
pupil.name = "小明";
pupil.age = 12;
pupil.testing();
pupil.setScore(88);
pupil.showInfo();
Gruduate gruduate = new Gruduate();
gruduate.name = "大明";
gruduate.age = 19;
gruduate.testing();
gruduate.setScore(500);
gruduate.showInfo();
}
}
The details of Extends:
1.子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访 问,要通过父类提供公共的方法去访问
package com.gdledu.extend_;
public class Base { //父类
//4个属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
public Base() {//无参构造器
System.out.println("base()....");
}
//父类提供一个public的方法
public int getN4() {
return n4;
}
public void test100() {
System.out.println("test100");
}
protected void test200() {
System.out.println("test200");
}
void test300() {
System.out.println("test300");
}
private void test400() {
System.out.println("test400");
}
public void calltest400(){
test400();
}
}
package com.gdledu.extend_;
public class Sub extends Base{
public Sub(){
System.out.println("sub()....");
}
public void sayOK(){//子类方法
//非私有的属性和方法可以在子类直接访问
System.out.println(n1 + n2 + n3);//n4 错误
test100();
test200();
test300();
//test400; 错误
//要通过父类提供的public方法访问n4
System.out.println("n4 = " + getN4());
//通过父类提供的public方法访问test400
calltest400();
}
}
package com.gdledu.extend_;
public class ExtendsDetail {
public static void main(String[] args) {
Sub sub = new Sub();
sub.sayOK();
}
}
2.子类必须调用父类的构造器, 完成父类的初始化
3.当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无 参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。
public class Base { //父类
// public Base() {//无参构造器
// System.out.println("父类base()构造器被调用....");
// }
public Base(String name, int age) {
System.out.println("父类Base(String name, int age)构造器被调用....");
}
public class Sub extends Base{
public Sub(){//无参构造器
//super(); 默认调用父类的无参构造器
super("ccc", 18);//当父类没有无参构造器时,使用super指向指定构造器调用
System.out.println("子类sub()构造器被调用....");
}
public Sub(String name){
super("cca", 19);
//do noting...
System.out.println("子类Sub(String name)构造器被调用...");
}
package com.gdledu.extend_;
public class ExtendsDetail {
public static void main(String[] args) {
Sub sub = new Sub();
System.out.println("===========");
Sub sub1 = new Sub("chubby");
}
}
4.如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
5.super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
6.super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
public class Sub extends Base {
public Sub(String name, int age) {
//1.调用父类的无参构造器
//super();//父类的无参构造器
//2.调用父类的Base(String name)构造器
//super("ccc");
//3.调用父类Base(String name, int age)构造器
//super必须放在第一行
super("ada",99);
//this("ccc");//报错
}
}
7.java 所有类都是 Object 类的子类, Object 是所有类的基类. ctrl + h 查看
8. 父类构造器的调用不限于直接父类! 将一直往上追溯直到 Object 类(顶级父类)
9.子类最多只能继承一个父类(指直接继承) ,即java 中是单继承机制
思考: 如何让 A 类继承 B 类和 C 类? 【A 继承 B , B 继承 C】
10.不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
The essence of extends:
package com.gdledu.extend_;
/**
* 讲解继承的本质
*/
public class ExtendsTheory {
public static void main(String[] args) {
Son son = new Son();//内存的布局
//?-> 这时请大家注意,要按照查找关系来返回信息
//(1) 首先看子类是否有该属性
//(2) 如果子类有这个属性,并且可以访问,则返回信息
//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object...
//(5) 如果找到但是为private 则报错,不会再往上级父类找
System.out.println(son.name);//返回就是大头儿子
//System.out.println(son.age);//返回的就是 39
//System.out.println(son.getAge());//返回的就是 39
System.out.println(son.hobby);//返回的就是旅游
}
}
class GrandPa { //爷类
String name = "大头爷爷";
String hobby = "旅游";
}
class Father extends GrandPa {//父类
String name = "大头爸爸";
private int age = 39;
public int getAge() {
return age;
}
}
class Son extends Father { //子类
String name = "大头儿子";
}
package com.gdledu.extend_.exercise;
public class Computer {
//编写 Computer 类,包含 CPU 、内存、硬盘等属性,
//getDetails 方法用于返回 Computer 的详细信息
private String cpu;
private int memory;
private int disk;
public Computer(String cpu, int memory, int disk) {
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
}
public String getDetails(){
return "cpu=" + cpu + " memory=" + memory + " disk=" + disk;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public int getDisk() {
return disk;
}
public void setDisk(int disk) {
this.disk = disk;
}
}
package com.gdledu.extend_.exercise;
//编写 PC 子类,继承 Computer 类,添加特有属性【品牌 brand】
public class PC extends Computer{
private String brand;
//这里IDEA根据继承的规则,自动吧构造器的调用写好
//这里也体现: 继承设计的基本思想,父类的构造器完成父类属性的初始化
//子类的构造器完成子类属性初始化
public PC(String cpu, int memory, int disk, String brand) {
super(cpu, memory, disk);
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String printInfo(){
return "电脑信息为:" + getDetails() + " brand=" + brand;
}
}
package com.gdledu.extend_.exercise;
//编写 NotePad 子类,继承 PC 类,添加特有属性【品牌 color】
public class NotePad extends PC{
private String color;
public NotePad(String cpu, int memory, int disk, String brand, String color) {
super(cpu, memory, disk, brand);
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void showInfo(){
System.out.println(printInfo() + " color=" + color);
}
}
package com.gdledu.extend_.exercise;
public class ExtendsExercise {
public static void main(String[] args) {
NotePad notePad = new NotePad("inter", 999, 999, "离谱", "bule");
notePad.showInfo();//输出电脑信息
}
}
2.super
super 代表父类的引用,用于访问父类的属性、方法、构造器
3.Override
package com.gdledu.override;
public class Animal {
public void cry(){
System.out.println("动物叫唤...");
}
}
package com.gdledu.override;
public class Dog extends Animal{
public void cry(){
//1.因为Dog是Animal的子类
//2.Dog的cry 方法和Animal的cry方法定义形式一样(名称、返回类型、参数)
//3.这时我们就说Dog的cry方法重写了Animal的cry方法
System.out.println("小狗汪汪叫...");
}
}
package com.gdledu.override;
public class Override01 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.cry();//输出:小狗汪汪叫
}
}
Detail
package com.gdledu.override;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String say(){
return "我叫" + name + "今年" + 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;
}
}
package com.gdledu.override;
public class Student extends Person{
private String id;
private double score;
public Student(String name, int age, String id, double score) {
super(name, age);
this.id = id;
this.score = score;
}
public String say(){
return super.say() + "id是" + id + "分数为" + score + "分";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
package com.gdledu.override;
public class OverrideExercise {
public static void main(String[] args) {
Person person = new Person("chubby",18);
System.out.println(person.say());
Student student = new Student("ccc",19,"2125110",99);
System.out.println(student.say());
}
}
4.Polymorphic
package com.gdledu.poly_.objectpoly_;
public class Animal {
public void cry(){
System.out.println("Animal cry() 动物在叫唤...");
}
}
package com.gdledu.poly_.objectpoly_;
public class Cat extends Animal{
public void cry() {
System.out.println("Cat cry() 小猫喵喵叫...");;
}
}
package com.gdledu.poly_.objectpoly_;
public class Dog extends Animal{
public void cry() {
System.out.println("Dog cry() 小狗汪汪叫...");
}
}
package com.gdledu.poly_.objectpoly_;
public class PolyObject {
public static void main(String[] args) {
//体验对象多态特点
//animal 编译类型就是Animal , 运行类型 Dog
Animal animal = new Dog();
//因为运行时,执行到该行时,animal运行类型是Dog,所以cry就是Dog的cry
animal.cry();//Dog cry() 小狗汪汪叫...
//animal 编译类型 Animal,运行类型是 Cat
animal = new Cat();
animal.cry();//Cat cry() 小猫喵喵叫...
}
}
package com.gdledu.poly_.detail;
public class Animal {
String name = "动物";
int age = 10;
public void sleep(){
System.out.println("睡");
}
public void run(){
System.out.println("跑");
}
public void eat(){
System.out.println("吃");
}
public void show(){
System.out.println("hello, 你好");
}
}
package com.gdledu.poly_.detail;
public class Cat extends Animal{
public void eat(){//猫捉老鼠
System.out.println("猫吃鱼");
}
public void catchMouse(){//Cat特有方法
System.out.println("猫捉老鼠");
}
}
package com.gdledu.poly_.detail;
public class PolyDetail {
public static void main(String[] args) {
//向上转型:父类的引用指向了子类的对象
//语法:父类类型引用名 = new 子类类型()
Animal animal = new Cat();
Object obj = new Cat();//也可以
//可以调用父类中的所有成员(需要遵守访问权限)
//但是不能调用子类的特有的成员
//因为在编译阶段,能调用哪些成员变量,是由编译类型来决定的
//animal.catchMouse() 错误
//最终的运行效果看子类的具体实现
animal.eat();//猫吃鱼
}
}
属性没有重写之说! 属性的值看编译类型
package com.gdledu.poly_.detail;
public class PolyDetail02 {
public static void main(String[] args) {
Base base = new Sub();
System.out.println(base.count);//10
Sub sub = new Sub();
System.out.println(sub.count);//20
}
}
class Base {//父类
int count = 10;//属性
}
class Sub extends Base{//子类
int count = 20;//属性
}
instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
package com.gdledu.poly_.detail;
public class PolyDetail03 {
public static void main(String[] args) {
BB bb = new BB();
System.out.println(bb instanceof BB);//ture
System.out.println(bb instanceof AA);//ture
//aa 编译类型AA 运行类型BB
AA aa = new BB();
System.out.println(aa instanceof AA);//ture
System.out.println(aa instanceof BB);//ture
Object obj = new Object();
System.out.println(obj instanceof AA);//false
String str = "hello";
System.out.println(str instanceof Object);//ture
}
}
class AA{}//父类
class BB extends AA{}//子类
DynamicBinding
PolyArray
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
public class Person {
private String name;
private int age;
public Person(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;
}
public String say(){
return name + "\t" + age;
}
}
package com.gdledu.poly_.polyarr_;
public class Teacher extends Person{
private double salary;
public Teacher(String name, int age, double salary) {
super(name, age);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String say() {
return super.say() + "\t" + salary;
}
public void teach(){
System.out.println("老师" + getName() + "正在授课");
}
}
package com.gdledu.poly_.polyarr_;
public class Student extends Person{
private double score;
public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String say() {
return super.say() + "\t" + score;
}
public void study(){
System.out.println("学生" + getName() + "正在学习");
}
}
package com.gdledu.poly_.polyarr_;
public class PolyArray {
public static void main(String[] args) {
Person[] persons = new Person[5];
persons[0] = new Person("aaa",18);
persons[1] = new Student("bbb",18,90);
persons[2] = new Student("ccc",18,80);
persons[3] = new Teacher("ddd",18,30000);
persons[4] = new Teacher("eee",18,60000);
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i].say());
if(persons[i] instanceof Student){
((Student)persons[i]).study();
//等价于
//Student student = (Student)person[i]
//student.study()
}else if (persons[i] instanceof Teacher){
((Teacher)persons[i]).teach();
}
}
}
}
PolyParameter
package com.gdledu.poly_.polyparameter;
public class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getAnnual(){
return 12 * salary;
}
}
package com.gdledu.poly_.polyparameter;
public class Worker extends Employee{
public Worker(String name, double salary) {
super(name, salary);
}
public void work(){
System.out.println("普通员工" + getName() + " is working");
}
@Override
public double getAnnual() {
return super.getAnnual();
}
}
package com.gdledu.poly_.polyparameter;
public class Manager extends Employee{
private double bonus;
public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public void manage(){
System.out.println("经理" + getName() + " is managing");
}
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
}
package com.gdledu.poly_.polyparameter;
public class PolyParameter {
public static void main(String[] args) {
Worker aaa = new Worker("aaa", 5000);
Manager bbb = new Manager("bbb", 20000, 50000);
PolyParameter polyParameter = new PolyParameter();
polyParameter.showEmpAnnual(aaa);
polyParameter.showEmpAnnual(bbb);
polyParameter.testWork(aaa);
polyParameter.testWork(bbb);
}
public void showEmpAnnual(Employee e){
System.out.println(e.getAnnual());
}
public void testWork(Employee e){
if(e instanceof Worker){
((Worker) e).work();
}else if(e instanceof Manager){
((Manager) e).manage();
}
}
}
The knowledge learning in the article comes from:【零基础 快速学Java】韩顺平 零基础30天学会Java_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1fh411y7R8?p=32