在实际开发中多数情况下会涉及到多个类之间的协作,因此,类和类之间就必然存在各种各样的关系,面向对象程序设计中,将类之间的关系分为两大类型:
依赖关系是一种比较紧密的关系,一般表现形式为一个方法的的执行,需要通过另一个对象的支持。
public class Course{ } public class Student { public void study(Course c){ } }关联关系是一种比依赖更为密切的关系,在代码层面的表现形式为,一个类的对象作为属性定义到另一个类中。
/**图书类*/ public class Book { int id; String name; BookManager manager; } /**图书管理员*/ public class BookManager { Book[] books; }聚合关系是一种比关联关系更为紧密的关系,表现是的两个类之间的一种包含,但是这个包含又不是必须或者不可分割的,从代码层面表现来看,跟关联是一致的,两者之间只是存在语义上的区别
//部门 public class Dept { int dno; String name; } //员工 public class Emp { int eno; String name; double sal; Dept dept; }####组合关系
组合关系是以上横向关系中最强的关系,表现的是部分跟整体的关系,两者之间通常表现为不可分割的一种关系,但是代码层面的表现跟关联,聚合是一致的,只是一种语义的区别。
public class People { Head head; Body body; } public class Head{ } public class Body{ }继承(Extends)是面向对象语言的三大特征之一,体现出的是一种类的上下级关系,因此是一种纵向关系;
java中通过继承,可以提高类的可扩展性,以及代码的可复用性;继承是一种 is a 的关系
语法
[修饰符] class 子类名 父类名称{
//属性、方法的声明
}
父类
public class Father { private String firstName; private double money; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }子类
public class Son extends Father{ }关于继承注意事项
java中一个父类可以存在多个子类
一个子类只能有一个父类(C++允许)
Java中虽然不能多继承,但是可以使用多重继承到达多继承目的
子类继承父类之后,子类中可以使用父类的非私有元素(属性,方法) —代码可复用
子类除了可以直接使用父类中的非私有元素外,还可以扩展自己的信息 --代码可扩展性
在创建子类对象时,通常是先调用父类构造器(不是创建父类对象)完成初始化操作,再执行子类构造器完成子类对象的创建以及初始化(调用默认构造器)
如果父类中不存在默认构造器,则子类中需要通过super显式的调用父类的其他构造器
构造器不能被继承,只能被子类调用(初始化子类时)
访问权限修饰符:在java中对于元素的访问提供了四种修饰符,分为为:private、default(不写)、protected、public;这四种修饰符分别对元素赋予了不同的访问权限,具体如下:
[外链图片转存失败(img-x2EfX8iO-1563446219364)(assets/1562831254670.png)]
java.lang.Object是java中所有类的终极父类,即java中所有的类都从该类继承,Object中提供了很多常用的方法:
toString()equals()hashCode()notify()notifyAll()wait()方法的重写和重载都是面向对象程序中多态的一种实现策略。重载和重写都是发生在方法上;
子类继承父类后,对父类中的某些方法覆盖,重新实现;在创建子类对象后再调用该方法时,此时使用的就是被重写之后的方法,而不是父类的方法
public class Animal{ public void eat(){ System.out.pritnln("吃食物"); } } public class Dog extends Animal{ /**方法重写*/ @Override public void eat(){ System.out.println("吃骨头"); } }注意事项:
方法的重写发生在继承关系的子类中,一般为子类重写父类的方法被重写的方法名称必须跟父类方法保持一致被重写的方法中参数的个数,顺序,类型必须跟父类方法一致,否则,该操作称之为重载而非重写被重写的方法返回值必须跟父类方法一致子类中重写的方法访问权限不能小于父类 “"是一个比较运算符,一般用于基本类型数据的比较,比较的是两个基本类型的值是否一致,如果使用“”比较两个引用类型对象时,此时比较的是两个对象的内存地址,所以,在对引用类型数据比较时不要使用”==".
equals是来自于java.lang.Object类中的方法,默认实现采用的是“==”完成,但是其他类可以通过对Object继承并重写equals方法,来实现对象的比较,但是通常情况下重写equals就必须重写hashcode,确保两个对象除了数据信息一致外,在内存中的地址也必须是一致,才能完全相等.
一般IDE中自带对于equals和hashCode重写的功能
例如:
public class User{ private int id; private String name; private String pwd; public User() { // TODO Auto-generated constructor stub } public User(int id, String name, String pwd) { super(); this.id = id; this.name = name; this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((pwd == null) ? 0 : pwd.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (pwd == null) { if (other.pwd != null) return false; } else if (!pwd.equals(other.pwd)) return false; return true; } }