Java面向对象 继承、方法的重写、关联和依赖

朝上 2022-01-15 02:32:10 阅读数:619

java 继承 面向对象 对象 面向

第1章 继承的概述及特点

1.1 继承的概念

1.1.1 继承的概述 is-a

继承是面向对象的核心特性,是面向对象的学习重点。

继承是代码复用的重要方式,是类与类之间的一种关系。

从类与类之间的设计关系来看,子类必须属于父类的一种时,才会继承。

父类抽取出了共性的内容,子类可以在父类基础上扩展新的属性与行为。

子类拥有父类的所有属性与方法,无需重新定义。并且可以直接使用非私有的父类成员。
关键字 extends

1.1案例

父类

package com.igeek.javase.ch02.extendss;
/** * @version 1.0 * @Description TODO * * 继承: is-a * 1.关键字 extends * 2.继承本质上是设计层面的思想,本意是提高代码的复用性 * 3.子类继承父类后,父类中的成员变量和成员方法子类都具备,并且子类还可以拓展新的属性和新的方法 * 4.创建的父类对象,可以使用父类中的成员属性和成员方法,但是不能使用子类拓展的属性及方法 * 5.Java中类与类之间是单继承 */
public class Animal {

private String name;
private String color;
private int age;
public Animal() {

}
public Animal(String name, String color, int age) {

this.name = name;
this.color = color;
this.age = age;
}
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public String getColor() {

return color;
}
public void setColor(String color) {

this.color = color;
}
public int getAge() {

return age;
}
public void setAge(int age) {

this.age = age;
}
//吃
public Animal eat(/*Animal a*/) /*throws Exception*/{

System.out.println("一只"+color+name+"在吃东西...");
return null;
}
}

子类

package com.igeek.javase.ch02.extendss;
/** * @version 1.0 * @Description TODO */
public class Dog extends Animal{

//
private String player;
public Dog() {

}
public Dog(String name, String color, int age, String player) {

super(name, color, age);
this.player = player;
}
public String getPlayer() {

return player;
}
public void setPlayer(String player) {

this.player = player;
}
//
public void kanjia(){

System.out.println("一只"+this.getAge()+"的"+this.getName()+"在看家...");
}
}

1.2 子类通过get&set方法访问父类成员变量

​ 当父类的成员变量用private修饰后,子类无法访问父类的成员变量,但是如果父类提供了public修饰的get/set方法,则子类可以通过get/set方法,正常访问父类的成员变量。

第2章 方法重写及继承内存图解

2.1 方法重写的概念与格式

2.1.1 方法重写的概述

当子类继承父类后,拥有了父类的成员并可以直接调用父类非私有方法。如果子类认为父类提供的方法不够强大,子类可以按照子类自身的逻辑重新定义继承过来的父类方法,这个重新定义父类方法的过程叫做方法重写。

方法重写后,调用该方法时不再调用父类的方法,而调用子类重写后的方法。

package com.igeek.javase.ch02.extendss;
/** * @version 1.0 * @Description TODO * * 方法重载 Overload * 1.发生在一个类中 * 2.方法名相同 * 3.参数列表不同(参数个数、参数顺序、参数数量不同) * 4.与返回值无关 * * 方法重写 Override * 1.发生在继承中,子类继承父类,子类重写父类的方法 * 2.方法名相同 * 3.形参必须一致 * 4.返回值:若是基本数据类型则返回值一致即可; * 若是引用数据类型,则子类的返回值类型不可以放大,只可以是<=父类的返回值类型 Object>Animal>Cat 父类>子类 * 5.访问权限修饰符:子类是不可以缩小范围的 public>protected>(default)>private * 6.抛出异常:子类抛出异常比父类小 Throwable>Exception>NullPointerException * * 注意: * [email protected]一旦标注在方法上,检测当前方法是否符合重写要求 * 2.子类重写父类的方法后,调用执行时会执行子类重写后的逻辑 */
public class Cat extends Animal{

public Cat() {

}
public Cat(String name, String color, int age) {

super(name, color, age);
}
//捕捉方法
public void zhua(){

System.out.println("一只"+this.getAge()+"岁的,小"+this.getName()+"在抓鱼...");
}
// Alt+Insert -> Override 或者 Ctrl+O
@Override
public Cat eat(/*Animal a*/) /*throws NullPointerException*/{

Cat cat = new Cat();
//默认调用父类的逻辑
//super.eat();
System.out.println("一只"+getName()+"在吃鱼...");
return cat;
}
}

Test

package com.igeek.javase.ch02.extendss;
/** * @version 1.0 * @Description TODO */
public class Test {

public static void main(String[] args) {

Cat cat = new Cat("小猫咪","花色",2);
cat.eat(); //Cat中方法重写eat(),执行时会按照子类的逻辑进行执行
cat.zhua();
System.out.println("------------------");
Tiger tiger = new Tiger();
tiger.setName("东北虎");
tiger.setColor("白色");
tiger.setAge(3);
tiger.eat();
tiger.hunt();
System.out.println("------------------");
Dog dog = new Dog("哈士奇","灰色",5,"彩钢儿");
dog.eat();
dog.kanjia();
System.out.println("------------------");
Animal animal = new Animal("动物","无色",1);
animal.eat();
//animal.hunt();
//animal.kanjia();
//animal.zhua();
}
}

输出

一只小猫咪在吃鱼...
一只2岁的,小小猫咪在抓鱼...
------------------
一只白色东北虎在吃东西...
东北虎在狩猎中...
------------------
一只灰色哈士奇在吃东西...
一只5的哈士奇在看家...
------------------
一只无色动物在吃东西...
  • 是否能被继承?
  •  1.成员变量、成员方法 可以继承
    
  •  2.私有的属性 可以继承
    
  •  3.静态的成员 不可以继承,静态成员是所有实例共享
    
  •  4.构造方法 不可以继承
    
  • 是否能进行方法重写?
  •  1.成员变量不存在重写的问题
    
  •  2.构造方法 不可以重写
    
  •  3.静态方法 不可以重写
    
  •  4.私有方法 不可以重写
    

2.2 继承后子父类构造方法调用先后顺序

2.2.1 继承中子父类构造调用顺序概述

在每次创建子类对象时,我们均会先初始化父类内容,再初始化其子类本身内容。目的在于子类对象中包含了其对应的父类存储空间,便可以包含了其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。

代码体现在子类的构造方法调用时,一定先调用父类的构造方法。

在这里插入图片描述

第3章 this与super

3.1 this与super访问普通成员

3.1.1 this和super访问注意事项

调用普通成员:

this.成员变量 可以访问本类对象的成员变量

super.成员变量 可以访问父类的成员变量

this.成员方法() 可以访问本类对象的成员方法

super.成员方法() 可以访问父类的成员方法

子类方法中

​ 访问子类自身的成员用this.

​ 访问父类的成员super.

就近原则:

​ 局部 > 本类成员 > 父类成员

3.2 super访问父类构造方法

3.2.1 super调用父类构造方法的格式

调用构造方法:

​ this(其他参数) 可以访问本类其他的构造方法

​ super(其他参数) 可以访问父类其他的构造方法

默认子类调用父类构造方法:

​ 子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super();

3.3 this访问子类构造方法

在子类构造中使用this() 或 this(参数类型 参数值…)的方法可以调用本类中的其他构造方法。但是最终都是要调用父类的构造方法,完成父类成员的初始化。

第4章 关联关系及依赖关系

4.1 关联关系

​ 对象和对象之间的连接。在Java中,关联关系的代码表现形式为一个类做为另一个类的属性类型存在。即“有”的关系:”has-a”

  • 关联关系 为了提高代码的复用率
  • 1.代码层面:一个类作为另外一个类的属性类型存在
    
  •  2.has-a 有
    
  •  3.一对一 、 一对多Phone[] phones、List<Phone> list
    
  •  4.强关联(组合关系)、弱关联(聚合关系)
    
  •  5.单向关联、双向关联
    
package com.igeek.javase.ch02.has;
import java.util.Arrays;
/** * @version 1.0 * @Description 关联关系 */
public class ClassTest {

public static void main(String[] args) {

Student stu1 = new Student("小红",100);
Student stu2 = new Student("小黑",101);
Student stu3 = new Student("小白",102);
Student[] stus = {
stu1,stu2,stu3};
Classes classes = new Classes("Java","班级1",stus);
// classes.setStudents(stus);
stu1.setClasses(classes);
stu2.setClasses(classes);
stu3.setClasses(classes);
//双向关联中 , toString()会互相调用的问题,造成堆栈溢出错误 , 一定要注意
System.out.println(classes);
System.out.println("-----------"+classes.getName()+"的学生信息如下------------");
for (Student student : classes.getStudents()) {

System.out.println(student);
}
}
}
class Classes{

private String label;
private String name;
//一对多 强关联 双向关联
private Student[] students = new Student[3];
public Classes() {

}
public Classes(String label, String name) {

this.label = label;
this.name = name;
}
public Classes(String label, String name, Student[] students) {

this.label = label;
this.name = name;
this.students = students;
}
/** * 获取 * @return label */
public String getLabel() {

return label;
}
/** * 设置 * @param label */
public void setLabel(String label) {

this.label = label;
}
/** * 获取 * @return name */
public String getName() {

return name;
}
/** * 设置 * @param name */
public void setName(String name) {

this.name = name;
}
/** * 获取 * @return students */
public Student[] getStudents() {

return students;
}
/** * 设置 * @param students */
public void setStudents(Student[] students) {

this.students = students;
}
/*public String toString() { return "Classes{label = " + label + ", name = " + name + ", students = " + Arrays.toString(students) + "}"; //StackOverflowError 堆栈溢出 }*/
public String toString() {

return "Classes{label = " + label + ", name = " + name + "}";
}
}
class Student{

private String name;
private int num;
//一对一 弱关联 双向关联
private Classes classes;
public Student() {

}
public Student(String name, int num) {

this.name = name;
this.num = num;
}
public Student(String name, int num, Classes classes) {

this.name = name;
this.num = num;
this.classes = classes;
}
/** * 获取 * @return name */
public String getName() {

return name;
}
/** * 设置 * @param name */
public void setName(String name) {

this.name = name;
}
/** * 获取 * @return num */
public int getNum() {

return num;
}
/** * 设置 * @param num */
public void setNum(int num) {

this.num = num;
}
/** * 获取 * @return classes */
public Classes getClasses() {

return classes;
}
/** * 设置 * @param classes */
public void setClasses(Classes classes) {

this.classes = classes;
}
public String toString() {

return "Student{name = " + name + ", num = " + num + ", classes = " + classes + "}";
}
}

4.2 依赖关系

依赖关系(use-a):指一个类A使用到了另一个类B。依赖关系的特性:这种关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。

  • 依赖关系 为了代码复用性
  •  1.代码层面 一个类作为另外一个类的方法形参类型存在
    
  •  2.use-a 用
    
  •  3.具备临时性,偶然性
    
public class Person {

private String name;
//上班的方法 类A使用到了另一个类B
public void work(Bus bus){

System.out.println(this.name+"乘坐"+bus.getName()+"去上班");
}
public Person() {

}
public Person(String name) {

this.name = name;
}
/** * 获取 * @return name */
public String getName() {

return name;
}
/** * 设置 * @param name */
public void setName(String name) {

this.name = name;
}
public String toString() {

return "Person{name = " + name + "}";
}
}
版权声明:本文为[朝上]所创,转载请带上原文链接,感谢。 https://blog.csdn.net/m0_51051154/article/details/120096186