继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。语法extends
public class Person {
private String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Student extends Person {
private double score;
}
//调用测试
Student s=new Student();
s.setName("yanjun");
s.age=100;
- 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
继承是is-a的相互关系
- Student extends Person
每个学生都是人
不是每个人都是学生
私有属性是否可被继承—两种答案
这个问题目前没有唯一的标准答案,网络上可以看到2种答案,分别是可继承和不可继承
- 可以被继承,但是由于private的限制,所以在子类中不能直接访问
- 不可以被继承。当构建子类对象时,首先创建父类对象,然后再创建子类对象,子类对象中包裹父类对象
子类除了拥有父类的属性和方法(拥有父类的所有成员,但是注意构造器和析构器不是成员),也可以创建自己的特性
继承的特点
Java中不支持多重继承,Java中要求任何的子类只能有一个直系的双亲类
public class Student extends Person,Random{
// 语法报错,多重继承
}
继承的优点
将所有子类的共同属性放入父类,实现代码共享,避免重复,提高开发效率
可以使得修改扩展,继承而来的实现比较简单
继承的缺陷
- 父类变,子类就必须变
- 继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的
- 继承是一种强耦合关系
继承的编码问题
public class Person {
public Person() {
System.out.println("Person....");
}
}
public class Student extends Person{
public Student() {
System.out.println("student....");
}
public static void main(String[] args) {
Student s1=new Student();
}
}
实际输出值为:
Person....
student....
结论:上溯流程中先查找所有的父类,然后才从根类开始逐层调用构造器
public class A{
private A(){} // 由于只有一个私有构造器,所以A类不能被继承
}
继承的语意是is a,所以【父类 obj=new 子类()】,比如Person p=new Student();
建议
建议的使用场景:把通用操作和方法放在父类中,将特殊的方法定义在子类中。
好处在于:1、避免代码重复。2、避免了人为因素导致的不一致性
java.lang.Object
所有Java类都直接或者间接的继承自Object类,那么Object中的方法也是其他所有类都拥有的
Object类中的常用方法
getClass方法用于获得当前对象的类型
Student s1=new Student();
System.out.println(s1.getClass());
//输出结果为 class com.yan2.Student
直接输出一个对象时,实际上默认输出的是该对象toString()方法的返回值。所有的Java类中都有这个方法,因为Java类都直接或者间接的继承于Object类,而Object类中定义了toString方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 输出内容是getClass()获取类型,再调用getName()获取类型名称,例如com.yan2.Student
//hashCode方法是Object类中定义的一个方法,Object类定义的方法默认用于获取当前对象存储地址相关的一个
整数,Integer.toHexString用于将整数转换为1进制字符串
System.out.println(new Random())实际显示为java.util.Random@6d06d69c
为了实现用户自定义输出格式,允许在类中覆盖定义toString方法
public String toString() {
return "Pig [weight=" + weight + ", color=" + color + "]";
}
在Object类中有equals方法的定义
public boolean equals(Object obj) {
return (this == obj); //实际上在Object中定义的equals比较的是对象的引用值
}
Student s1=new Student(); s1.setId(1L);
Student s2=new Student(); s2.setId(1L);
System.out.println(s1==s2);
System.out.println(s1.equals(s2));//因为equals是通过Object继承到的方法,所以这里的equals的实现
原理还是==比较
如果需要修改比较规则,则需要在Student类中重新覆盖定义equals方法,例如比较规则为id
public class Student {
private Long id;
public boolean equals(Object obj) {
if(obj!=null && obj instanceof Student) {
Student temp=(Student)obj;
long k1=id.longValue();//代码不够完善,因为调用方法前没有判null
long k2=temp.getId().longValue();
return k1==k2;
}
return false;
}
//get/set方法省略
hashCode()方法返回一个整形数值,表示该对象的哈希码值
源代码
public native int hashCode(); //native表示该方法使用C/C++通过对等类的方式实现
Student s1=new Student();
System.out.println(s1.hashCode()); //366712642
- 如果两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等
- 两个对象调用hasCode()返回的哈希码相等,这两个对象不一定相等
特殊关键字
包package是类或接口的容器
什么是包
- 包是类的组织方式,提供名空间和访问控制
- 类似于文件系统的组织
声明包中的类package
语法:package 包名称;
- 声明包要求是源代码文件的第一个语句
- 程序中最多只能有一条package语句,没有包定义的源代码文件成为默认包中的一部分 :
- 程序中如果有package语句,该语句必须是第一条语句(前面只能有注释或空行)
包的作用
- 包能将相关的源代码文件组织在一起
- 包减少了名称冲突带来的问题
- 可以使用package指明源文件中的类属于哪个具体的包
包的使用
- 如果其他人想使用包中类,则需要使用全名
- 为了简化书写,Java提供了import语句: import package_name.*;
- 引入包中的某一个类:import java.util.ArrayList;
引入包import
- Java缺省引入的包为java.lang
- 引入包中的类: import 包名称.类名称;例如import java.util.Date;
- 引入整个包; import 包名称.* ;例如 import java.util.* ;
- 不引入包而是用类,则需要是用类的全名: 包名.类名,例如java.util.Date dd=new java.util.Date();
包的文件组织和类路径CLASSPATH
在类路径中定义包的位置
.- 代表当前目录,为默认值
- 类文件存放的位置:类路径中的目录\包名称对应的路径
- 缺省包default package
- 源代码文件中没有package语句声明,且类文件位于CLASSPATH所定义的目录中
- 满足以上条件的所有类被认为处在同一个包中,这个包被称为缺省包
Classpath描述了Java虚拟机在运行一个Class时在哪些路径中加载要运行的类以及运行的类要用到的类。当一个程
序找不到他所需的其他类文件时,系统会自动到CLASSPATH环境变量所指明的路径中去查找第三方提供的类和用
户定义的类
Java中常用的包
- java.applet用于提供Applet开发的支持,目前已经被ash所替代,很少使用,只有在某些地图系统中还有使用
- java.awt和javax.swing用于单机软件或者c/s应用中的界面开发
- java.io用于输入、输出操作
- java.lang语言包,默认自动加载的包
- java.net用于网络编程
- java.util工具包,是Java提供的一些工具类