一、继承关系案例
父类非私有的属性和方法可以在子类直接访问
子类必须调用父类的构造器,完成父类的初始化,类似有鸡才有蛋,有老子才有儿子
第1步:父类
public class TopBase {
public TopBase() {
System.out.println("l am top parent");
}
}
第2步:儿子类
package com.lian.pojo.a;
public class Base extends TopBase{
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
// public Base(){
// System.out.println("base()...");
// }
public void test1000(){
System.out.println("test1000");
}
protected void test2000(){
System.out.println("test2000");
}
void test3000(){
System.out.println("test3000");
}
private void test4000(){
System.out.println("test4000...");
}
public void callTest4000(){
test4000();
}
public Base(int n1, int n2) {
System.out.println("parent base have constructor Base(int n1, int n2)");
}
public Base(String name){
System.out.println("parent have constructor Base(String name)");
}
public int getN1() {
return n1;
}
public void setN1(int n1) {
this.n1 = n1;
}
public int getN2() {
return n2;
}
public void setN2(int n2) {
this.n2 = n2;
}
public int getN3() {
return n3;
}
public void setN3(int n3) {
this.n3 = n3;
}
public int getN4() {
return n4;
}
public void setN4(int n4) {
this.n4 = n4;
}
}
第3步:孙子类
package com.lian.pojo.a;
public class Sub extends Base{
//因为子类必须要调用父类的无参构造器,而如果父类没有无参构造器,则子类就必须要用父类的有参构造器,每个类默认拥有无参构造器(默认有),如果写了有参构造器就必须将无参构造器写出来,否则无参构造器就没有啦
public Sub(){
//先有老子,才有儿子,所以必须先初始化父类
super(3,4); //子类通过super调用父类的有参构造
//super(); //子类的无参构造默认调用了父类的无参构造
System.out.println("sub()...");
}
public Sub(String name){
super(3,4);
System.out.println("sub son constructor was distributed");
}
public Sub(int n1, int n2) {
super(n1, n2);
}
public Sub(String name,int age){
super("dan");
System.out.println("son constructor...");
}
public void sayOk(){
//父类非私有的属性和方法可以在子类直接访问
//私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
//'n4' has private access in 'com.lian.pojo.a.Base'
//test4000()' has private access in 'com.lian.pojo.a.Base'
System.out.print(n1+" "+n2+" "+n3+" "+getN4()+"\n");
test1000();
test2000();
test3000();
//sub不能直接调用父类Base的test4000方法,但是父类中的方法 callTest4000()方法有权利用,那就帮个忙啦
callTest4000();
}
}
第4步:测试类
package com.lian.pojo.a;
/**
* 子类最多只能继承一个父类,一个儿子只有一个亲生爸爸
* 如果A继承B,B继承C,这样A就拥有了C的公共的属性和方法使用权
*/
public class ExtendsDetail {
public static void main(String[] args) {
//Sub sub = new Sub();
//子类不论调用哪个构造器,都会调用其父类的无参构造器
//Sub sub2 = new Sub("pi");
//sub.sayOk();
Sub sub2 = new Sub("pi",4);
}
}
二、子类创建的内存布局案例
package com.lian.pojo.a;
/**
* 子类创建的内存布局案例
*/
public class GrandPa {
public static void main(String[] args) {
Son son = new Son();
//System.out.println("name:"+son.name);
//System.out.println("age: "+son.age);
//System.out.println("hobby :"+son.hobby);
/**
* 获取子类信息,按照查找关系来返回信息
* 1、首先看子类是否有该属性
* 2、如果子类有此属性,并且可以访问,则返回信息
* 3、如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息)
* 4、如果父类没有此属性,就按照规则3继续找上级父类,直到object
*/
System.out.println(son.name); //返回 son
System.out.println(son.getAge()); //返回 10
System.out.println(son.hobby); //返回 travel
}
}
class GrandFather {
String name = "grandFather";
String hobby = "travel";
}
class Father extends GrandFather{
String name = "Father";
private int age = 10;
//age是本类才可以有权限使用的,本类方法可以获取到值
//本类public方法有权利获得Age值,别人借助此public方法也就可以获取到值啦
public int getAge() {
return age;
}
}
class Son extends Father{
String name = "son";
}
三、习题小结
第1题
package com.lian.pojo.b;
/**
* 问题: main 函数中,B b = new B();会输出什么
* a
* b name
* b
*
* 1、子类一定会先实例化父类的无参构造器,如果父类没有无参构造器,就实例化父类的有参构造器
* 2、流程: 父类构造器 —— 子类构造器 ,先有老子,后才有儿子
*
*/
class Demo{
public static void main(String[] args) {
B b = new B();
}
}
class A {
public A() {
System.out.println("a");
}
public A(String name) {
System.out.println("a name");
}
}
class B extends A{
public B() {
//super(); //子类构造器默认有父类无参构造器,如果父类没有声明无参构造器,此处就写父类有参构造器
this("abc");
System.out.println("b");
}
public B(String name){
System.out.println("b name");
}
}
第2题
/**
* 问题2:执行main方法,打印结果
* a
* cry b have constructor
* c have constructor
* c no constructor
*/
package com.lian.pojo.c;
public class Demo {
public static void main(String[] args) {
C c = new C();
}
}
class A{
public A() {
System.out.println("a");
}
}
class B extends A{
public B() {
System.out.println("b no constructor");
}
public B(String name){
// super(); //子类默认调用父类的无参构造,如果父类没有无参构造,就调用父类的有参构造
System.out.println(name + " b have constructor");
}
}
class C extends B{
public C() {
this("happy");
System.out.println("c no constructor");
}
public C(String name) {
super("cry");
System.out.println("c have constructor");
}
}
第3题
computer类
package com.lian.pojo.d;
public class Computer {
private String cpu;
private int memory;
private int disk;
//默认有无参构造器
// public Computer() {
// }
//如果有 有参构造器,且没有显式声明无参构造器的话,本类默认的无参构造器就没啦
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;
}
}
PC类
package com.lian.pojo.d;
/**
* 类和人一样,必须先有爸爸,才有儿子
* 1、子类继承父类,因为子类初始化 一定要 先将父类初始化,所以父类必须要有构造器
* 2、类 默认拥有无参构造器,子类默认继承父类的 无参构造器
* 3、如果父类写了有参构造器,没有显示声明无参构造器的话,无参构造器就默认不存在了
* 4、如果父类写了有参构造器,没有显示声明无参构造器,子类就必须继承父类的 有参构造器
*/
public class PC extends Computer{
private String brand;
//父类没有无参构造器,子类就继承父类的有参构造器
//There is no default constructor available in 'com.lian.pojo.d.Computer'
//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 void printInfo(){
System.out.println("pc information");
System.out.println(getDetails()+",brand= "+brand);
}
}
测试类
package com.lian.pojo.d;
public class Test {
public static void main(String[] args) {
PC pc = new PC("intel",16,500,"ibm");
pc.printInfo();
}
}
//打印结果
//cpu: intel, memory: 16,disk: 500,brand= ibm