重载
1.在一个类中
2.方法名相同
3.参数列表不同(个数不同或类型不同或顺序不同)
传参
public class C244 {
public static void main(String[] args) {
// num的栈地址是100
int num = 1;
C244 c = new C244();
// 当参数类型是原始类型时,传入的参数的值是数据本身
c.add(num);
// ?
System.out.println("num=" + num);
}
/**
* 对参数num加1
* @param num 参数,一个整数 num在栈中的地址是101
*/
public void add(int num){
num+=2;
}
}
public class C245 {
public static void main(String[] args) {
// 栈中student的地址是100,它里面保存的是name1学生的堆地址2000
Student student = new Student(1,"name1");
C245 c = new C245();
c.changeStudent(student);
System.out.println(student.getName());
}
/**
* 改变学生姓名
* @param student 栈中student参数地址是101,它里面是student对象堆地址
*/
public void changeStudent(Student student) {
student.setName("new name");
}
}
对于原始类型的参数,传入的是变量的值,对于引用类型的参数,传入的是对象的地址。
不一样:一个是数值,一个是地址。
一样: 都是变量中的值。
public class C246 {
public static void main(String[] args) {
// 栈中student的地址是100,它里面保存的是name1学生的堆地址2000
Student student = new Student(1, "name1");
C246 c = new C246();
c.changeStudent(student);
System.out.println(student.getName());
}
/**
* 改变学生姓名
*
* @param student 栈中student参数地址是101,它里面是student对象堆地址
*/
public void changeStudent(Student student) {
// 让101中的地址改为3000
student = new Student(2,"name2");
}
}
变量,参数,指针
public class C247 {
public static void main(String[] args) {
String name = "Tom";
C247 c = new C247();
c.change(name);
System.out.println(name);
}
public void change(String msg){
//msg += " hello";
// String是不变的,当让String变化时,它就会产生一个新的String
msg.concat("hello");
// 相当于 msg += " hello";
}
}
继承
子类继承父类,高效。
1.子类不用写重复的代码
2.维护代码不用对相似(相同)代码进行多处维护。
开发和维护都高效。
缺点:打破了封装,原来不继承是无法访问父类的成员,继承后就可以访问了。
创建子类时,首先要创建它依赖的父类对象,是一个依赖链。
(A->B->C->D->E) 当创建E时,要先创建D的对象,依次最终要创建A,耗费时间空间
当继承层次多时,使的代码阅读困难,代码的复杂度变高。
public class A {
public A(){
System.out.println("A init");
}
public static void main(String[] args) {
B b = new B();
}
}
class B extends A{
public B(){
System.out.println("B init");
}
}
Java类文件中可以同时写多个class,但是只能有一个类是public,并且这个类名和文件名要一致。
如果一个java类文件中只有一个类,并且这个类不是public的,则类名和文件名可以不一致。
类中的游离块语句会先执行,再执行构造方法,在生成的class文件中看到游离块实际是放在构造方法的前部分。
类中的代码,在类中只能定义变量和赋值,无法写其他代码,比如:打印,计算等,这些代码都要写在方法中,而游离块中是不做限制的。原因是游离块最终还是在构造方法中。
重写
子类继承父类
子类中的方法名,方法参数列表必须和父类完全相同,方法返回类型要兼容。
方法的访问修饰符必须大于等于父类的(可以发扬广大,不可失传)
protected (父类)
子类就必须是protected或public
@Override 注解,说明存在重写的现象,可以强制编译器进行检查,检查方法是否重写正确
public class Father {
protected void say(){
System.out.println("你好");
}
public void work(){
System.out.println("work in father");
}
public static void main(String[] args) {
Son son = new Son();
son.say();
son.work();
}
}
class Son extends Father{
@Override
protected void say(){
System.out.println("hello ");
}
}
父类中的方法被子类继承后,又重新定义就是重写,表现出子类重写后的现象。
父类方法和子类方法发生重写后,子类方法的返回类型必须和父类方法的返回类型兼容(不需要完全相同)
protected Father getObject(){
return this;
}
@Override
protected Son getObject(){
return this;
}
重写方法getObject子类中返回的是Son,而Son是Father的子类,它们在类型上兼容(一家子)
属性的继承
当父类中的属性不是私有可以继承到子类中,当子类中有同名的属性时,会隐藏父类的属性。
有点像方法的重写(覆盖)
重点:父类的属性可以被继承,但无法覆盖,这个和方法不一样。