Java当中子类继承父类的一些特点,和对象的一些特点

面向对象的本质就是把写好的代码复制来复制去,隐藏代码和显示代码,执行的都是显示的代码,创建对象,就是复制代码但是看不见,调用方法就是让代码能够看见,或者间能够看见

创建对象,复制代码到创建对象的地方(看不见)

继承—复制以前的代码加一些代码,或者写一个名字一样的代码(重写方法),当重写后的代码和之前父类的代码优先执行重写后的代码。

重写后的代码相当于显示,被重写的代码隐藏

创建多态,复制父类代码和子类重写父类的代码,(子类父类共有的代码)(子类的本质就是复制父类的代码加一些东西,)

执行的依旧是显示的代码

俗话说的传递参数无非就是复制代码后删除原本的代码,垃圾回收机制就是删除原本的代码,释放空间

1、当子类继承父类后子类当中会看不见的复制粘贴父类的属性和方法

2、子类默认在子类的构造方法(有参无参都调用)当中调用父类的无参构造,也就是说明在子类的构造方法当中会默认通过super(); (看不见)来调用父类的无参构造方法

3、当继承体系是这样的,孙子类继承父亲,父亲继承爷爷,当实例化孙子的无参构造的时候,会默认调用父类的无参构造,执行顺序是爷爷无参构造 - >父亲无参构造 - >孙子无参构造

4、当实例化化孙子的有参构造的时候,默认并调用父类的无参构造和爷爷的无参构造,执行顺序是这样的
爷爷无参构造 - >父亲无参构造 - > 孙子有参构造

5、如果想让直接通过new 类名称(参数);的方式去调用父类的有参构造方法侧需要通过子类当中(在第一行)super关键字来手动调用父类的有参构造,当调用了父类的有参构造之后就不会调用无参构造了

class AA {
	AA() {// 每办法在子类里面调用这个
		System.out.println("AAAA");
	}
	AA(String aa) {
		System.out.println(aa);
	}
}
class BB extends AA {
	// 老师这个删了为什么会报错
	// 这里是不是没有
	BB() {
		System.out.println("BBBBBB");
		System.out.println("---------------");
	}
	BB(String bb) {
		System.out.println(bb);
	}
}
class CC extends BB {
	CC() {
		System.out.println("-------------");
	}
	CC(String cc) {
		System.out.println(cc);
	}
}
public class Test02 {
	public static void main(String[] args) {
		CC c = new CC("aaaaaaaaaa");
	}
}

6、当实例化孙子的有参构造,并依次在孙子的有参构造和父亲的有参构造当中通过super来调用父类的有参构造的时候,执行顺序是,爷爷有参构造 - > 父亲有参构造 -> 孙子有参构造

7、子类可以通过super来调用父类的方法来为自己服务,当将对应的值通过super(参数)传递给父类的构造方法的时候,该值也会被子类所继承,并可以直接使用

8、父类获得到的值子类也会获得到,即使是子类通过某种方式提交给父类,那么这个值,子类父类同时都可以访问到,也就是说子类传递到父类的属性或者方法,可以通过子类调用父类方法的方式获取到

9、也就是说明super调用的不是父类当中的方法和属性,而调用的是子类继承到父类的东西,也就是调用的是子类拥有父类的属性,实际使用的还依旧是子类当中的属性和方法,即使子类重写父类的方法(使用多态会默认调用子类的方法),子类拥有父类当中的方法依旧存在,子类依旧可以调用该方法

10、子类重写父类的方法,子类拥有父类的方法并不会被覆盖,因为在子类重写父类方法之后依旧可以调用被重写的方法,子类重写父类方法实际上是复制一份父类的方法,只不过在执行的时候优先使用子类当中的方法

分别定义两个类

public class Teacher {
	public String tname;
	public String tid;
	public Teacher() {
		// TODO Auto-generated constructor stub
	}
	public Teacher(String tname, String tid) {
		this.tname = tname;
		this.tid = tid;
	}
	public void work() {
		System.out.println(tname+tid);
	}
}
public class HuLiTeacher extends Teacher {
	String tkm;
	public HuLiTeacher() {
		// TODO Auto-generated constructor stub
	}
	public HuLiTeacher(String tname, String tid, String tkm) {
		super(tname, tid);
		this.tkm = tkm;
	}
	public void work() {
		super.work();// 但是这里却取不到上面赋予的值,这是怎么回事啊
		System.out.println("老师科目" + tkm);
	}
}

子类继承父类可以这样理解
在这里插入图片描述
蓝色没有的(属性和方法)红色有的(属性和方法)直接使用默认红色,蓝色也有的(属性和方法)红色也有的(属性和方法),优先使用蓝色,蓝色有的(属性和方法)红色没有的(属性和方法)直接使用蓝色,如果想要单独调用需要通过this,或者super

也就是说super与其说是在调用父类的属性和方法,还不如说是在调用这些隐藏的属性和方法,

当创建子类对象或者本类使用属性或方法的时候,子类当中有和隐藏的属性和方法重名的时候,则优先使用的是子类当中的,如果都要使用则需要在子类当中通过super或者this来调用,都没有的时候则默认调用的是隐藏的方法和属性,或者不是隐藏的(选择其一)。(表明看起来是调用了父类的方法和属性)
也可以理解为这样

在这里插入图片描述
创建对象的过程也可以理解为复制代码的过程,复制之后看不到而言,通过创建引用的方式为这段看不见的起名字,可以通过引用来调用看不见的代码

多态

在这里插入图片描述
多态方法参数是对象的时候,可以理解为接收复制的代码是父类原本的代码,和子类重写的代码,当做是父类的代码来使用

创建多态可以理解为这里复制 的代码 是父类继承的属性和方法(super)和子类重写父类的属性或方法 的代码
如果重写优先使用子类,父类的和子类重写父类的

多态作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写2113出通用的代码,做出通用的编程,以适应需求的不断变化。子类复制了父类的代码,然后子类可以看做是父类的代码,因为多态使用的是他们公共的代码。

赋值之后,父类型的引用就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。

多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。

如果只是创建子类对象可以理解为复制的代码是子类当中可以看到和从父类继承看不到的代码的全部代码

方法当中的参数就相当于将代码复制到当前方法当中,如果传递的子类那就把父类和子类共有的属性和方法显示

abstract的目的就是必须让隐藏的代码必须显示出来用(方法或者属性)提醒用户使用,但是也是必须使用

单static 修饰就是代码不能复制只能直接使用,可以修改

单finall 修饰意思就是代码不能修改,可以复制,但是不可以被子类复制,因为子类的本质就是修改
类和方法都不可以被复制,修改

static final 就是代码不能复制也不能修改

子类无法重写父类的静态方法和final方法和private
但是可以继承静态方法,无法继承final和private

子类无法重写父类的静态方法,因为静态方法只有一份,如果重写另外一份静态方法那就是另外一份静态方法

int arr0[];// 创建数组不开辟空间

		arr0 = new int[18];// 开辟内存空间

		int arr1[] = new int[5];// 创建数组开辟内存空间 ,但是不赋值

		// 创建数组并同时开辟内存空间对其进行赋值
		int arr2[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 10 };

		// 声明引用和赋值,必须在同一句
		double arr3[] = { 2, 3, 4, 56, 5 };// 创建数组并同时开辟内存空间对其进行赋值

		for (int i = 0; i < arr3.length; i++) {
			System.out.println(arr3[i]);
		}

		for (int a : arr2) {
			System.out.println(a);
		}
public class Student {

	public int sid;
	public String sname;
	public int age;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(int sid, String sname, int age) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.age = age;
	}

}
// 创建对象数组

		// 没有复制代码,只是齐了5个名字
		Student[] s = new Student[5];// 创建了存储student引用的5个空间,但是没有创建Student对象

		// 复制代码到名字1
		s[0] = new Student(1, "张一", 17);// 创建对象将值赋予到对象数组的引用上,也就是让数组当中的各个引用指向该对象
		s[1] = new Student(2, "张二", 15);// 创建对象将值赋予到对象数组的引用上,也就是让数组当中的引用指向该对象
		s[2] = new Student(3, "张三", 18);// 创建对象将值赋予到对象数组的引用上,也就是让数组当中的引用指向该对象
		s[3] = new Student(6, "张四", 32);// 创建对象将值赋予到对象数组的引用上,也就是让数组当中的引用指向该对象
		s[4] = new Student(5, "张无", 45);// 创建对象将值赋予到对象数组的引用上,也就是让数组当中的引用指向该对象

		for (int i = 0; i < s.length; i++) {

			System.out.print(s[i].sid);
			System.out.print(s[i].sname);
			System.out.println(s[i].age);

		}

		String[] s2 =  {"aaaa","sasasas"};
		
		for (int i = 0; i < s2.length; i++) {
			System.out.println(s2[i]);
		}

在这里插入图片描述
字符串直接赋值通过双等号比较的时候比较的是值(但是实际上也是比较的地址,只不过这个时候是一个内存空间)
按值传递复制的是值
按引用传递传递的是代码
字符串在创建对象new 的时候通过双等号比较两个字符串是比较的是地址值

如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错。
如何解决呢?
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
默认情况是自动访问父类的无参构造,先创建父类,然后创建子类,如果父类没有无参构造,就需要在子类的构造方法当中调用父类有参构造,来创建父类,然后才是创建子类(先有父类后有子类)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章