一、继承
1.含义
含义: 继承是一种使用已有的类创建新类的机制,是指在已有类的基础上扩展其功能。继承中的分为
子类
和父类
,父类又叫超类,子类又叫派生类。
注意: 子类可以继承父类的属性和行为,同时可以增加自己特有的属性和行为。父类可以是Java中的类,也可以是自己编写的类。(通俗来讲就是:我们可以继承父亲的财产,同时也可以继承自己的财产。)
2.继承的实现—>extends关键字的引入
实现继承需要在类声明中使用extends关键字来声明一个类继承另一个类!
格式如下:
//子类继承父类声明情况:
[修饰符] class 子类名 extends 父类名{
......
}
例如:
//儿子继承父亲的财产,子类声明如下:
public class Son extends Father{
.......
}
3.案例
//父类声明如下:
public class Father{
//属性定义
String name;
int age;
//方法定义
public void printInfo(){
System.oyt.println("姓名:"+name+"\n年龄:"+age);
}
}
//子类的声明如下:
public class Son extends Father{
}
4.继承特点
1.Java只支持单重继承,不支持多重继承,即一个子类只能有一个直接父类。
例如下面这种情况不对:
Class A {}
Class B extends A {}
Class C extends A,B {} // C类不可以同时继承A类和B类
2.多个类可以继承一个父类,即一个父类可以有多个子类。
例如下面这种情况是允许的:
Class A {}
Class B extends A {}
Class C extends A {} // B类和C类同时继承A类
3. Java继承多层继承,即继承具有传递性,子类还可以有子类。
例如下面这种情况是允许的:
Class A {}
Class B extends A {} // B类继承A类
Class C extends B{} // C类继承B类
5.*问题解惑
子类可以继承父类所有的成员变量么?
子类的继承性取决于子类和父类是否在同一包中以及成员的访问修饰级别,主要有以下几种情况:
1. 如果子类和父类在同一包中,子类可以继承父类非private修饰的成员变量和成员方法。
2. 如果子类和父类不在同一包中,子类只能继承父类public、protected修饰的成员变量和方法。
3.子类无法继承父类的构造方法。
二、变量隐藏
1.含义
含义: 当子类定义的成员变量和父类中定义的成员变量同名时(类型可不同),称子类隐藏了父类的成员变量,当子类对象调用这个成员变量时,一定是调用在子类中声明定义的那个成员变量,而不是从父类继承的变量。
2.案例
//父类的声明
class Father{
public int y=100;
public void printOfather(){
System.out.println("Father的y="+y);
}
}
//子类的声明
class Son extends Father{
public double y=0.5;
public void printOfson(){
System.out.println("Son的y="+y);c
}
}
//主函数中:
public class EX7_2{
public static void main(String[] args){
Son son = new Son();
son.y=10.5;
son.printOfather();
son.printOfson();
}
}
//运行结果为:
father的y=100;
son的y=10.5
三、方法重写
1.含义
含义: 当子类定义一个方法,这个方法
返回类型
,方法名
,参数列表
与从父类继承的方法完全相同
时,我们称之为方法重写;子类一旦重写了父类的方法,则子类对象一再调用该方法时一定调用的是重写后的方法。
注意:子类重写父类方法时访问权限不能降低。
2.案例
//父类
public class Person {
//共有属性
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//共有行为
public void printInfo() {
System.out.println("姓名:"+name+"\n年龄:"+age);
}
}
//子类
public class Student extends Person {
//新增属性
private String department;
//新增行为
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
//重写printInfo()方法
public void printInfo() {
System.out.println("姓名:"+name+"\n年龄:"+age+"\n系别:"+department);
}
}
//主函数中:
public class EX7_5 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("小明");
stu.setAge(18);
stu.printInfo();
stu.setDepartment("信息工程学院");
}
}
//运行结果:
姓名:小明
年龄:18
系别:信息工程学院
3.*方法重载与方法重写的区别
1.
方法重载
时是出现在同一类中不同的方法,只要求方法的名字相同,方法参数类别不同。
2.方法重写
是在继承中出现的,是指子类定义跟父类完全相同的方法,修改方法的实现,达到改变继承的行为的目的。
四、super关键字
利用super关键字进行代码优化,以减少代码重复的问题!
1.在子类中使用super关键字
(1)super关键字在构造方法中的使用
案例
//父类
public class Person {
//共有属性
String name;
int age;
//共有行为
public void printInfo() {
System.out.println("姓名:"+name+"\n年龄:"+age);
}
}
//子类
public class Student extends Person {
//新增属性
String department;
//新增行为
public String getDepartment() {
return department;
}
//重写printInfo()方法
public void printInfo() {
super.printInfo();//调用父类中被重复的方法
System.out.println("系别:"+department);
}
}
//主函数中:
public class EX7_5 {
public static void main(String[] args) {
Student stu = new Student();
stu.name("小明");
stu.age(18);
stu.printInfo();
stu.department("信息工程学院");
}
}
//运行结果:
姓名:小明
年龄:18
系别:信息工程学院
(2)super关键字在成员方法中的使用
案例
//父类:
public class Person {
public Person() {
System.out.println("Person无参构造方法!");
}
}
//子类:
public class Student extends Person{
public Student() {
super();//super在构造方法中的使用,可以省略
System.out.println("Student无参构造方法!");
}
}
//主函数:
public class EX7_5 {
public static void main(String[] args) {
Student stu1 = new Student();
}
}
//运行结果:
Person无参构造方法!
Student无参构造方法!
2.*注意
在子类的构造方法中使用super:
1. 子类的构造方法中没有显示调用父类的构造方法,也没有使用this关键字调用重载的其它构造方法,系统则会默认调用父类无参数的构造方法。(相当于在子类的构造中省略了super();
)
2. 如果子类的构造方法中通过super显示的调用父类有参数的构造方法,那将执行父类应有的相应参数的构造方法。
3. 如果子类的构造方法中通过this显示调用自身的其它构造方法,在相应构造方法中应满足以上两条中的一条。
4.super调用父类的构造方法必须作为子类构造方法中的第一条语句。
* super既可以用在构造方法中又可以用在成员方法中,且在构造方法中既可以写带参数的super方法,也可以写无参数的super方法。
五、final关键字
1.final 修饰类
final修饰的类不能被继承,也就是说final修饰的类不能有子类。
案例
//父类
public final class Person{
}
//被final修饰的类不能有子类,即以下代码需注释
//class Student extends Person{
//}
2.final修饰变量
final修饰的变量(成员变量和局部变量)是常量,只能赋值一次。 也就是说,final修饰的变量一旦被赋值,其值不能改变。如果再次对该变量进行赋值,则程序会在编译时报错。
案例
//当final修饰成员变量时:
//错误代码:
public class Person{
final String MALE; //必须初始化,因为final修饰的变量是一个常量,必须初始化。
}
//修改后正确代码:
public class Person{
final String MALE = "Hello";
}
//final修饰局部变量:
//错误代码:
public class Person{
public void print(final String s){
s="Hello";//final修饰的变量不能二次赋值,因为在调用此print方法时已经给s赋过一次值,这里相当于再次给s赋值,相当于二次赋值,所以不对
}
}
//修改后正确代码:
public class Person{
public void print(final String s){
System.out.println("s的值为"+s);
}
}
3.final修饰方法
final修饰的方法不允许被重写。
案例
//错误代码
public class Person{
public final void print(){
}
class Student extends Person{
public void print(){//因为在父类中用final修饰了次方法,被final修饰的类是不能被重写的,所以此代码不对
}
}
}
//修改后正确代码:
public class Person{
public final void print(){
}
class Student extends Person{
}
}
六、abstract关键字
abstract关键字既可以修饰类,又可以就是修饰方法。
1.abstract关键字修饰类
由abstract修饰的类叫做抽象类,格式如下:
abstract class A{
…
}
注:被abstract修饰的类不能被实例化,也就是不允许用抽象类创造对象。需要产生子类,由子类创造对象。
案例
//父类
public abstract class Person{
public void print(){
System.out.println("final修饰的类不能被创建对象!");
}
}
//子类
public class Student{
public void print(){
System.out.println("final修饰的类不能被创建对象,既由它的子类来完成对象的创建!");
}
}
//主函数:
public static void main(String[] args){
// new Person();//final修饰的类不能被创建对象, 即此处需要被注释掉!
new Student();
}
2.abstract关键字修饰方法
由abstract修饰的方法叫做抽象方法,抽象方法没有方法体。
案例
//父类
public abstract class Person{
public abstract void print();//抽象方法没有方法体,需要有它的子类来完成结构体创建!
}
//子类
public class Student{
public void print(){
System.out.println("由abstract修饰的方法叫做抽象方法,抽象方法没有方法体。!");
}
}
3.*总结
1. abstract关键字可以修饰类也可以修饰方法,abstract修饰的类叫做抽象类,由abstract修饰的方法叫做抽象方法。
2. 抽象类不能创建对象,创建对象由子类来负责。
3. 抽象方法没有方法体,方法体也是由子类来给出的。
4. 抽象方法必须在抽象类中。
七、Object与toString
1.Object类
Java类库中有一个超级类------java.lang.Object,它是一切类的“祖先”。
所有的Java类都直接或者间接的继承了java.lang.Object类。
注:如果一个类在声明时没有使用extends关键字来声明父类,那么它的直接父类就是Object。
案例
//下面两种写法都可以:
public class Person{ //第一种写法
}
public class Person extends Object{ //第二种写法
}
2.toString方法
toString() 是Object中的一个特殊方法,该方法通常用于打印对象的自身信息。
案例
//子类
public class Person extends Object{
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
//主函数:
public class EX7_6 {
public static void main(String[] args) {
Person p = new Person("张三",23);
System.out.println(p.toString());//此处的还可以写为:System.out.println(p); toString可以省略
}
}
八、访问控制
1.Java中的访问修饰符
Java语言中提供了private、default(没有用public、protected及private中任何一种修饰)、protected和public四个访问修饰符来控制类及类的方法和变量的访问权限。
1.访问修饰符权限列表
访问修饰符 | 同一类中 | 同一包中 | 不同包子类中 | 不同包中 |
---|---|---|---|---|
private | Yes | |||
默认的 | Yes | Yes | ||
protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
1.private: private修饰的成员变量及方法,只有本类可以访问,而包内包外的任何类都不能访问。
2.default: 默认访问权限的类、变量及方法,包内任何类都可以访问,当然也包括同一类的问题,而对于包外的任何类都不能访问它。default重点突出包。
3.protected: 用protected修饰变量及方法,包内的任何类可以访问,同时包外的继承了该类的子类也能访问。
4.public: 用public修饰的类、变量及方法,包内及包外的任何类(包括子类和普通类)都可以访问。
.