Unit04 - 继承的意义(下) 、 访问控制 、 static和final
1.方法的重写(Override):重新写、覆盖
1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
2)重写方法被调用时,看对象的类型
2.方法重写与重载的区别:------常见面试题
1)重写(Override):
1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
1.2)遵循"运行期"绑定,根据对象的类型来调用方法
2)重载(Overload):
2.1)发生在同一类中,方法名称相同,参数列表不同,方法体不同
2.2)遵循"编译期"绑定,根据引用(参数)的类型来绑定方法
3.package:
1)作用:避免类名的冲突
2)包名可以有层次结构
3)类的全称: 包名.类名
4)建议:包名所有字母都小写
import:
1)同包中的类可以直接访问
2)不同包中的类不能直接访问,方式如下两种:
2.1)先import声明类而后再直接使用---建议
2.2)类的全称------太繁琐,不建议
4.访问控制修饰符:
1)public:公开的,任何类
2)private:私有的,本类
3)protected:受保护的,本类、子类、同包类
4)默认的:什么也不写,本类、同包类
类的访问修饰符有:public和默认的
类中成员的访问修饰符有:如上4种都可以
5.static:静态的
1)静态变量:
1.1)由static修饰
1.2)属于类的,存储在方法区中,只有一份
1.3)常常通过类名点来访问
1.4)何时用:所有对象所共享的数据(图片、音频、视频等)
2)静态方法:
2.1)由static修饰
2.2)属于类的,存储在方法区中,只有一份
2.3)常常通过类名点来访问
2.4)静态方法没有隐式的this传递,
静态方法中不能直接访问实例成员
2.5)何时用:方法的操作仅与参数相关而与对象无关
3)静态块:
3.1)由static修饰
3.2)属于类的,在类被加载期间自动执行,
类只被加载一次,所以静态块也只执行一次
3.3)何时用:常常用于初始化静态资源(图片、音频、视频等)
6.final:最终的
1)修饰变量:变量不可被改变
2)修饰方法:方法不可被重写
3)修饰类: 类不可被继承
静态方法
静态方法没有隐式this,
没有this意味着没有对象,
没有对象就无法直接访问实例成员,
因为实例成员必须得对象来访问
成员变量:
1)实例变量:
没有static修饰
属于对象的,存储在堆中,
有几个对象就有几份
通过对象点来访问
2)静态变量:
有static修饰
属于类的,存储在方法区中,
只有一份
通过类名点来访问
与对象无关-------适合静态
与对象有关-------不适合静态
静态类:
无论a1,a2,a3,...,a100,
去sort(arr),最终的结果都一样
说明sort()方法,与对象无关,而仅与参数相关
Arrays.sort(arr);
假设sort()不是静态的:
Arrays a1 = new Arrays();
a1.sort(arr);
Arrays a2 = new Arrays();
a2.sort(arr);
Arrays a3 = new Arrays();
a3.sort(arr);
无论m1,m2,m3...,m100,
去sqrt(25),最终结果都是一样的
说明,sqrt()方法与对象无关,而仅与参数相关
double a = Math.sqrt(25);
假设sqrt()不是静态的
Math m1 = new Math();
double a = m1.sqrt(25);
Math m2 = new Math();
duoble b = m2.sqrt(25);
Math m3 = new Math();
double c = m3.sqrt(25);
数据私有化(private),行为公开化(public):
class Card{
private String cardId;
private String cardPwd;
private double balance;
public boolean payMoney(double money){
if(balance>=money){
balance-=money;
return true;
}else{
return false;
}
}
public boolean checkPwd(String pwd){
if(pwd.equals(cardPwd)){
return true;
}else{
return false;
}
}
}
建议命名规则:
域名反写 . 项目名称 . 模块名称 . 类名
cn.tedu . a . student .
com.taobao . b . teacher .
com.jd
重载看引用,重写看对象
编译期:.java,经编译,生成.class-----检查语法
运行期:JVM加载.class并运行.class-----加载对象
重写:继承了一个餐厅(中餐)
A:继承后依然还是做中餐---------不需要重写
B:继承后改为做西餐-------------重写
C:继承后在中餐基础上加西餐-----重写+super
静态变量
OverrideDemo,练习重写
package oo.day04; //重写的演示 public class OverrideDemo { public static void main(String[] args) { } } /* * 重写需遵循"两同两小一大"原则: * -----------一般都是一模一样 * 1)两同: * 1.1)方法名称相同 * 1.2)参数列表相同 * 2)两小: * 2.1)子类方法的返回值类型小于或等于父类的 * 2.1.1)void时,必须相等 * 2.1.2)基本类型时,必须相等 * 2.1.3)引用类型时,小于或等于 * 2.2)子类方法抛出的异常小于或等于父类的-----异常之后 * 3)一大: * 3.1)子类方法的访问权限大于或等于父类的-----访问控制修饰符之后 */ //父类大,子类小 class Aoo{ void say(){} double sayHi(){return 0.0;} public Aoo test(){return null;} Boo show(){return null;} } class Boo extends Aoo{ //int say(){return 1;} //编译错误,void时必须相等 //int sayHi(){return 0.0;} //编译错误,基本类型时必须相等 public Boo test(){return null;} //正确,引用类型小于 //Aoo show(){return null;} //编译错误,引用类型必须小于或等于 }
OverloadOverrideDemo,练习重写与重载的区别
package oo.day04; //重写与重载的区别 public class OverloadOverrideDemo { public static void main(String[] args) { //重载看引用,重写看对象 Eoo eoo = new Eoo(); Coo o = new Doo(); //向上造型 eoo.test(o); //重载看引用(参数) } } class Eoo{ void test(Coo o){ System.out.println("父型参数"); o.show(); //重写看对象 } void test(Doo o){ System.out.println("子型参数"); o.show(); } } class Coo{ void show(){ System.out.println("父类Show"); } } class Doo extends Coo{ void show(){ System.out.println("子类Show"); } }
StaticDemo,练习static
自己整理的:
package oo.day04.vis; public class StaticDemo { public static void main(String[] args) { Joo o1 = new Joo(); o1.show(); Joo o2 = new Joo(); o2.show(); System.out.println(Joo.b); //2,刚刚已经长成2了 Koo.test(); //因为是静态的,所以通过类名访问 Loo o3 = new Loo(); //加载类的时候自动执行,只执行一次,类只加载一次 Loo o4 = new Loo(); //加载过了,方法区不变,直接执行构造方法, } } class Loo{ static { System.out.println("静态块"); } Loo(){ System.out.println("构造方法"); } } class Koo{ int a; //对象访问 static int b; //类访问 void show(){ //有隐藏的this System.out.println(a); //this.b System.out.println(b); //Koo.b } static void test(){ //没有隐式this传递 // System.out.println(a); //没有this方法,报错,a必须要要通过对象访问 System.out.println(b); //通过类名访问 } } class Joo{ int a; //实例变量 static int b; //静态变量 Joo(){ a++; b++; } void show(){ System.out.println("a="+a); System.out.println("b="+b); } } //静态方法不能直接访问实例成员?? class Aoo{ int a; //实例变量 对象点 static int b; //静态变量 类名点 属于类 void show(){ //实例方法 有隐式this System.out.println(a); //this.a System.out.println(b); //Aoo.b } static void test(){ //静态方法 没有隐式this // System.out.println(this.a); //编译错误 System.out.println(b); } }
老师的:
package oo.day04; //static的演示 public class StaticDemo { public static void main(String[] args) { Joo o1 = new Joo(); o1.show(); Joo o2 = new Joo(); o2.show(); System.out.println(Joo.b); //2 System.out.println(o1.b); //2,不建议 System.out.println(o2.b); //2 Koo.test(); Loo o3 = new Loo(); Loo o4 = new Loo(); } } class Loo{ //演示静态块 static{ System.out.println("静态块"); } Loo(){ System.out.println("构造方法"); } } class Koo{ //演示静态方法 int a; static int b; void show(){ System.out.println(a); System.out.println(b); } static void test(){ //没有隐式this传递 //System.out.println(a); //没有this意味着没有对象,而a必须要通过对象来访问,所以编译错误 System.out.println(b); } } class Joo{ //演示静态变量 int a; //实例变量:堆中,有几个对象有几份 static int b; //静态变量:方法区中,一份 Joo(){ a++; b++; } void show(){ System.out.println("a="+a); System.out.println("b="+b); } }
演示final
package oo.day04; //final的演示 public class FinalDemo { public static void main(String[] args) { } } final class Poo{} //演示final修饰类 //class Qoo extends Poo{} //编译错误,final的类不能被继承 class Roo{} final class Soo extends Roo{} class Noo{ //演示final修饰方法 void show(){} final void test(){} } class Ooo extends Noo{ void show(){} //void test(){} //编译错误,final的方法不能被重写 } /* * final可以修饰成员变量,只有两种初始化方式: * 1)声明同时初始化 * 2)构造方法中初始化 * final可以修饰局部变量,只要在使用之前初始化即可 */ class Moo{ //演示final修饰变量 final int a = 5; final int b; Moo(){ b = 6; } void show(){ final int c; //用之前初始化即可 //a = 55; //编译错误,final的变量不能被改变 } }
程序一:演示public,protected,private
package oo.day04; public class Foo { public int a; //任何类 protected int b; //本类、子类、同包类 int c; //本类、同包类 private int d; //本类 void show(){ a = 1; b = 2; c = 3; d = 4; } } class Goo{ //演示private void show(){ Foo o = new Foo(); o.a = 1; o.b = 2; o.c = 3; //o.d = 4; } }
package oo.day04.vis; import oo.day04.Foo; public class Hoo { //演示包 void show(){ Foo o = new Foo(); o.a = 1; //o.b = 2; //o.c = 3; //o.d = 4; } } class Ioo extends Foo{ //演示protected,跨包继承 void show(){ a = 1; b = 2; //c = 3; //d = 4; } }