19.子类实例化过程
在子类的构造函数中,必须调用父类的构造函数
由于子类只能继承父类的成员变量和成员函数,而不能继承父类的构造函数,所以要用super()
super() 一定要在构造函数的第一条语句,和this()一样
在子类的构造函数中,必须调用父类的构造函数
由于子类只能继承父类的成员变量和成员函数,而不能继承父类的构造函数,所以要用super()
super() 一定要在构造函数的第一条语句,和this()一样
(如果没有写super,编译器会自动加上一个无参的super)
super() 调用父类的构造函数
this() 调用本类构造函数
super() 调用父类的构造函数
this() 调用本类构造函数
20.函数的复写(override)
复写(override) :在具有父子关系的两个类当中,父类和子类各具有一个函数,这两个函数的定义(返回值类型,函数名,参数列表)完全相同,那这两个函数的关系就是复写override.
javac *.java 编译所有的.java文件
super.introduce() 调用父类的成员函数
这行代码随便写在第几条语句
重载和复写的区别
重载(overload):在一个类里面,函数名相同,参数列表不同
复写( override ):在两个类里面,要有继承关系,这两个函数定义(函数名,参数列表)完全相同
复写(override) :在具有父子关系的两个类当中,父类和子类各具有一个函数,这两个函数的定义(返回值类型,函数名,参数列表)完全相同,那这两个函数的关系就是复写override.
javac *.java 编译所有的.java文件
super.introduce() 调用父类的成员函数
这行代码随便写在第几条语句
重载和复写的区别
重载(overload):在一个类里面,函数名相同,参数列表不同
复写( override ):在两个类里面,要有继承关系,这两个函数定义(函数名,参数列表)完全相同
21.对象的向上转型-将子类的对象赋值给父类的引用
1.一个引用能调用哪些成员(变量和函数),取决于这个引用的类型定义
2.一个引用调用的是哪一个方法,取决于这个引用所指向的对象
2.一个引用调用的是哪一个方法,取决于这个引用所指向的对象
//Student extends Person
Student s =new Student();
Person p = s;
p.address错误,因为Person中没有address这个成员变量,只有Student中有
p.introduce()会调用Student中introduce()而不是Person中的introduce()(参见2)。
p.introduce()会调用Student中introduce()而不是Person中的introduce()(参见2)。
当然,如果Person中没有introduce()也会报错(参见1)
向上转型一定会成功
向上转型一定会成功
向下转型 ----
先把一个对象向上转型,再向下转型 ,不能直接向下转
//Student extends Person
//正确的向下转型
Person p = new Student();
Student s = (Student)p;
//错误的向下转型
//Person p = new Person();
//Student s = (Student)p;
22.面向对象应用(一)----打印机
23.抽象类和抽象函数
类是抽象的,对象是具体的
只有函数的定义(返回值类型,函数名,参数列表),没有函数体(大括号以及大括号中的内容)的函数被称作
抽象函数
例:abstract void fun();
抽象类:使用abstract定的类被称之为抽象类,不能生成对象
抽象类是有构造函数的,这个构造函数是为子类准备的(因为它的子类生成对象时会调用super())
1.抽象类不能生成对象(基类:子类需要继承它),但它的子类可以生成对象。
2.如果一个类中包含有抽象(abstract)函数,那么这个类必须被声明为抽象(abstract)类
3.如果一个类中没有抽象函数,那么这个类也可以被声明为抽象类
抽象类的子类通过复写(override)抽象类的抽象函数,就可以不用声明为abstract,这样就可以生成对象了;
为什么抽象类不能生成对象(如果调用抽象函数怎么办,毕竟抽象函数没有函数体)
public abstract class Person {
Person(){
System.out.println("Person的构造函数");
}
String name;
int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
void introduce(){
System.out.println("我的名字是"+name+",我的年龄是"+age);
}
abstract void eat();
}
public class Chinese extends Person{
String address;
Chinese(){
System.out.println("Chinese的构造函数");
}
Chinese(String name,int age,String address){
super(name,age);
this.address = address;
}
//复写父类的抽象函数,就不用定义为abstract类
void eat(){
//也可以通过this调用从父类中继承的成员变量
System.out.println(this.name+"用筷子吃饭");
super.introduce();
}
}
24.为什么用抽象类
为了防止忘记在子类中复写那个函数,所以定义成抽象函数。如果忘记复写了,编译就不能通过
(当然抽象类还有其他作用)
现代编程希望实现:如果一段代码在语义上是有错误的,那么在语法上也应该是有错误的
模板模式就是以抽象类为基础
25.包和访问权限(一)
1.什么是Java中的软件包:软件包为Java类提供了命名空间
2.打包需要用package指令
//将类放置到一个包当中,需要用 package 包名
package mars;
class Test{
}
//编译时需要使用-d参数,该参数的作用是依照包名生成相应的文件夹
javac -d . Test.java
//-d 根据包名生成文件夹(编译生成的Test.class文件将会放在这个文件夹下)
//.(点) 在哪生成文件夹(点表示在当前目录下生成文件夹)
例:
表示在 E:\src目录下生成 mars文件夹,里面会有编译后生成的
Test.class文件
例:
将生成文件夹放在C:\windows下
一个类的全名应该是”包名“+”.“+"类名",一旦打包后,类的全称就发生了变化
再也不能用java Test来运行程序了,只能用java mars.Test来运行
cd ..
回到上一级目录
包名的命名规范
1.要求包名所有字母都小写
2.包名一般情况下是你的域名倒过来写
//域名:marsdroid.org 包名应该是org.marsdroid
如果用package org.marsdroid
那么会生成org文件夹下的marsdroid文件夹下面的
Test.class文件
26.包和访问权限(二)
包的导入
import org.mars.*;
//导入org.mars这个包下所有的类
pubic :如果一个类被声明为public权限,那么它的类名必须与文件名相同
//public可以修饰类,成员变量和成员函数。没有任何限制,同一个包当中,或者不同包中的类都可以自由访问
public class Person{
//类名必须为Person.java
}
两个类在不同的包中,如果一个类想访问另外一个类,那么被访问的类应该有public权限,如果想访问类的成员变量和成员函数,那么成员变量和成员函数也应该有public权限
private:可以修饰成员变量和成员函数,只能在本类中使用
default:包级别访问权限(不写权限修饰符就是default权限)(如果两个类在同一个包中,那么一个
类可以任意访问另一个类的成员变量和成员函数)
27.包和访问权限(三)
protected:protected权限首先拥有和default一样的功能,但是该权限只能修饰成员变量和成员函数。可以跨包继承
//如果子类和父类不在同一个包中,子类可以继承到父类中default权限的成员变量和成员函数。但是由于权限不够,
无法使用。(有争议)
public >protected>default>private
类,成员变量,函数的权限应该尽可能小