目录
一、java继承
1.父类
public class Person {
public Double height;
public String name;
public char sex;
public void run(){
System.out.println("任何人都可以跑");
}
public void a(){
System.out.println("...........");
}
}
2.子类
-------继承父类:子类 extends 父类
public class Student extends Person{//继承person
public void study(){
System.out.println("学生学习");
}
}
3.Test类
4.总结
继承的本质就是代码的复用,子类复用父类的代码,子类可以使用父类已经写好的代码,子类就不需要重新写了,但是父类不能使用子类的代码
5.java的继承层次
java的继承层次是不能互相继承的;一个类可以被多个类当成父类,一个子类只能有一个父类(java仅支持单继承)
二、重载和重写
1.java的修饰符
本类 | 子类 | 同包 | 不同包 | |
public | 可以访问 | 可以访问 | 可以访问 | 可以访问 |
protected | 可以访问 | 可以访问 | 可以访问 | 无法访问 |
不写 | 可以访问 | 可以访问 | 可以访问 | 无法访问 |
private | 可以访问 | 无法访问 | 无法访问 | 无法访问 |
总结:
public修饰的代码,本类和其他类都是可以访问的
private修饰的代码,本类可以访问,但是其他类不可以访问的
2.普通方法
(1)方法是有访问权限的
(2)方法必须写上返回数据的类型,如果不需要返回数据就写void
例:
public void student(){
System.out.println("好好学习");
return;
}
private int age(){
return 18;
}
(3)在同一个类中,方法名可以相同但是方法的签名不能相同
方法的签名=方法名+参数列表的类型
参数列表的类型有string、int、double...
例:
①
②
(4)方法上可以用其他的关键字进行修饰,比如static、final
3.构造器
也叫构造方法/构造函数
(1)作用
在创建对象的时候给对象的变量赋值
(2)特点
①在类中构造函数必须和类名相同
②.在类中有一个默认的不显示的无参数的构造器,
一旦你在类中写一个构造器,那么那个无参构造器就会被覆盖
③构造器不需要写返回值
④.一个类中可以有多个构造函数
4.重载
发生在本类中;
在同一类中,方法名相同但是列表不同就是方法的重载;
能提高方法的功能
比如,下面的就是方法的重载:
public void stu(){
}
public void stu(String name){
}
public void stu(String name,int age){
}
5.重写
(1)是什么
发生在父子类当中,子类重新实现父类方法的功能
(2)为什么会重写?
继承的本质是代码的复用,但是在复用的过程中,父类的方法的实现不一定完全适用子类,这个时候就涉及到方法的重写
方法重写之后,子类对象调用的也是重写后的方法
重写前:
A.
public class A{
public void run(){
System.out.println("A跑的很快");
}
}
B.
public class B extends A{
}
Test.
public class Test {
public static void main(String[] args) {
B b=new B();
b.run();
}
}
运行结果:
重写后:
A.
public class A{
public void run(){
System.out.println("A跑的很快");
}
}
B.
public class B extends A{
public void run(){
System.out.println("B跑的很快");
}
}
Test.
public class Test {
public static void main(String[] args) {
B b=new B();
b.run();
}
}
运行结果:
6.类的执行顺序
代码:
public class Test extends Base{
//static修饰的代码块在main方法执行之前执行,其目的是修饰main方法
public Test(){
System.out.println("test constructor");
}
public static void main(String[] args) {
new Test();
}
static {
System.out.println("test static");
}
}
class Base{
static {
System.out.println("base static");
}
public Base(){
System.out.println("base constructor");
}
}
运行结果:
这样输出的原因:
先扫描再编译;先执行父类,再执行子类
程序执行先去找main()方法启动程序
程序执行的过程
1.扫描Test类,发现有父类Base类,先去扫描父类,发现Base类没有父类
2.将Base.class加载进方法区,此时Base类中的static代码块执行
3.将Test.class加载进方法区,此时Test类中的static代码块执行
4,main方法入栈,main执行new Test();去创建Test类的对象
5.创建子类对象之前先创建父类对象,所以先执行Base()构造器,再执行Test()构造器
7.再看方法的重写
重写前:
A.
public class A{
public void run(){
System.out.println("A跑的很快");
}
public void flay(){
System.out.println("飞得很高");
}
}
B.
public class B extends A{
}
Test.
public class Test {
public static void main(String[] args) {
B b=new B();
b.run();
b.flay();
}
}
流程图:
重写后1:
A.
public class A{
public void run(){
System.out.println("A跑的很快");
}
public void flay(){
System.out.println("飞得很高");
}
}
B.
public class B extends A{
public void run(){
System.out.println("B跑的很快");
}
}
Test.
public class Test {
public static void main(String[] args) {
B b=new B();
b.run();
b.flay();
}
}
流程图:
重写后2:
A.
public class A{
public void run(){
System.out.println("A跑的很快");
}
public void flay(){
System.out.println("飞得很高");
}
}
B.
public class B extends A{
public void run(){
System.out.println("B跑的很快");
}
}
Test.
public class Test {
public static void main(String[] args) {
B b=new B();
b.run();
b.flay();
A a=new A();
a.run();
}
}
流程图: