1.final修饰变量
被final修饰的变量只能赋值一次 一般用在全局常量
final int i;
i = 1;
注意:修饰成员变量的时候,定义的时候就要赋值.修饰局部变量的时候可以先定义,再赋值!
public static final double pi;
final修饰类:不能被继承
final修饰方法:不能被复写
final修饰变量:只能赋值一次(成员变量定义和赋值,局部变量可以先定义再赋值!)
2.toString()方法
Person p = new Person();
System.out.println(p);
cn.zhm.asd.Person@46205df9
全限定名:包名+类名 @:应该是一个分隔符 46205df9:16进制的地址值,hashCode();返回该对象的哈希码值;
它是一个哈希码值,可以理解成底层的一种特殊算法得出来的数值
3.复写toString方法
地址值就是hashCode()在控制;toString方法.返回地址值等字符串,这对我们来说,没什么意义!一般来说:比如人,我们要打印这个人,我们要看到的是他的属性信息,姓名,年龄,等.所以复写他的toString()
public String toString(){ returnname+":"+age; } |
我们的打印语句System.out.println();打印一个什么东西,就自动调用他的toString方法,就相当于我们不写他也给我们加上.
System.out.println(p.toString()); |
4.总结:
1.继承关键字——extends
public class Dog extens Pet{
}
2.继承中私有的成员无法继承,构造函数也无法继承,无法重写。
3.不可以使用public或protected修饰类。
4.super-对当前对象的直接父类对象的默认引用
public Dog(String name,String strain) {
super(name);
this.strain = strain;
}
5.构造器中不能同时调用super构造器和this构造器,只能调用其中一个,且必须是第一行
6.所有的类直接间接继承Object类
7.java中只能单继承,可以多层继承
8.方法的重写:
1.相同方法名
2.相同参数列表
3.返回值类型一致
4.重写方法权限大于等于被重写方法
9.快速生成重写方法 —— 方法名+Alt+/
10.重载和重写的区别:
重载:方法名相同,参数列表不同,与返回值类型,访问修饰符无关
重写:与父类一模一样
11.抽象类不能实例化
public abstract class Pet{
}//调用子类构造器的时候 会默认调用父类的无参构造器 super放在前面
12.抽象方法必须写在抽象类中
13.抽象类中可以没有抽象方法
14.//调用子类构造器的时候 会默认调用父类的无参构造器 super放在前面
15.//调用子类构造器的时候 如果显示调用父类的构造器之后 就不会再调用父类的无参构造器
16.//重写只能发生在子类 方法的重载只能发生在同一个类
5.抽象类
//abstract 抽象类 抽象类不能 仅 提供一个方法而不是提供具体的执行方法 ,目的在于在子类重写此方法
public abstract void print(); }
注意:抽象类可以没有抽象方法,象类 抽象方法必须搭配抽抽象类可以有构造器
public abstract class Pet {
public Pet(){
System.out.println("二五仔");
}
}
public abstract class Pet {
public Pet(String name, int health, int love) { super(); //当所有类没有继承父类的时候 自动默认继承object类 超级类 this.name = name; this.health = health; this.love = love; }
}
6.重写
System.out.print(getName()+getHealth()+getLove());
}
@Override //重写只能发生在子类 方法的重载只能发生在同一个类
public void print() {
// TODO Auto-generated method stub
System.out.println(strain);
重写:就是有继承关系,子类重写父类的方法。方法名和参数列表包括返回值都得一模一样
7.重载
8.构造函数
class Fu{ Fu(){ System.out.println("父类的构造函数"); } } class Zi extends Fu{ Zi(){ System.out.println("子类的构造函数"); } } |
这个时候new Zi();发现不仅调用了子类的构造函数,还执行了父类的构造函数,而且父类的还先执行
子类构造函数中默认第一行有一条隐式的语句super();
Super()的意思是调用父类的无参构造函数。我们之前的this();就是调用自己的构造函数。其实super和this的用法一致,一个代表自己,一个代表父类;
this();必须是第一行。
现在我们把父类的无参构造函数改成有参的构造函数;
Fu(inti){ System.out.println("父类的构造函数"); } |
这样super();就访问不到了吧,就报错!这时候怎么办,我们可以手动写出调用父类的有参构造函数
Zi(){ super(1); System.out.println("子类的构造函数"); } |
class Fu{ public String name; Fu(String name){ this.name = name; } } class Zi extends Fu{ Zi(String name){
} } |
直接把name传过去让父类赋值就行了!
Zi(String name){ super(name); } |
跟this(name);差不多嘛!
现在又改一下:
class Fu{ public String name; Fu(){} Fu(String name){ this.name = name; } } class Zi extends Fu{ Zi(){} Zi(String name){ this(); super(name); } } |
去掉super(name);为什么不报错!我们子类的构造函数必须要访问到父类的构造函数!不然就报错,那这里为什么没报错。因为这里this();调用了自己的无参构造函数,
而无参构造函数里面有一句隐式的super();所以也拿到父类的构造函数!
总结就是:子类的构造函数必须拿到父类的任意一个构造函数!