Static
static表示静态,是Java中的一个修饰符,可以修饰成员方法、成员变量
静态变量:
被static修饰的成员变量,叫静态变量
特点: 被该类所有对象共享
调用方式:1.类名调用 2.对象名调用
静态方法:
被static修饰的成员方法,叫静态方法
特点:多用于测试类和工具类中 Javabean类很少使用
调用方式:在本类中:直接调用 在其他类中:1.类名调用 2.对象名调用
工具类:帮我们最一些事情,但不描述任何事物的类
JavaBean | 描述一类事物的类 |
测试类 | 检查其他的类是否书写正确,带有main方法,是程序的入口 |
工具类 | 不描述事物,帮我们做事的类 |
工具类:
- 类名见名之意
- 私有化构造方法
exp1:
编写一个数组的工具类:ArrUtil
- 提供一个工具方法printArr方法,用于返回整数数组的内容。
- 提供一个工具方法getAerage方法,用于返回平均分。
- 定义一个测试类,调用工具类中的方法。
工具类:
public class ArrUtil {
private ArrUtil(){
}
public static void printArr(int[] arr){
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length-1){
System.out.print(arr[i]);
}else{
System.out.print(arr[i]+",");
}
}
System.out.print("]");
}
public static double aervge(int[] arr){
int sum = 0;
int count = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum+arr[i];
count++;
}
return sum/count;
}
}
测试:
public class ArrUtilTest {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,7,9};
ArrUtil.printArr(arr);
System.out.println("平均数为:"+ArrUtil.aervge(arr));
}
}
static内存图:
静态变量优先于对象出现,是随着类的加载而加载的
static不属于对象
那些属性可以用static修饰:共享的属性
Static注意事项:
- 静态方法只能访问静态变量和静态方法
- 非静态方法可以访问所有
- 静态方法没有this关键字
Main方法:
public static void main(String[] args){}
public:被JVM调用,权限足够大
static:被JVM调用,不用创建对象,直接类名访问
因为main方法是静态的,所以测试类中其他的方法也需要是静态的
void:JVM调用,不需要给虚拟机返回值
mian:通用名称,但被JVM识别
String[] args:以前用于接收键盘录入数据,现在没用
继承
假如我们要定义如下类: 学生类,老师类和工人类,分析如下。
-
学生类 属性:姓名,年龄 行为:吃饭,睡觉
-
老师类 属性:姓名,年龄,薪水 行为:吃饭,睡觉,教书
-
班主任 属性:姓名,年龄,薪水 行为:吃饭,睡觉,管理
如果我们定义了这三个类去开发一个系统,那么这三个类中就存在大量重复的信息(属性:姓名,年龄。行为:吃饭,睡觉)。假如多个类中存在相同属性和行为时,我们可以将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。
extends关键字:
Java中使用extends关键字可以让一个类和另一个类建立继承关系
class 父类 {
...
}class 子类 extends 父类 {
...
}
public calss student extends person{}
student称为:子类 person称为:父类
继承的好处:
-
提高代码的复用性(减少代码冗余,相同代码重复利用)。
-
使类与类之间产生了关系。
-
在父类的基础上增加其他功能,使子类更加的强大
当类与类之间存在相同的内容,并满足子类是父类中的一种,就可以考虑继承优化代码
继承的特点:
Java只支持单继承,不支持多继承,但支持多层继承
单继承:一个子类只能继承一个父类
不支持多继承:子类不能同时继承多个父类
多次继承:c继承b,b继承a。a是b及直接父类,a是c的间接父类
每一个类都直接或者间接的继承于Object类
当父类的方法被private修饰时:子类就无法访问只能在本类中访问
why?若子类继承俩个父类,若两个父类中有相同名称的方法,子类调用父类的方法就会出错
子类能继承父类的内容:
构造方法:不能
成员变量:若父类成员变量被private修饰,子类不可调用(但是可以继承,不能直接的调用),反之则可
成员方法:JVM会从最顶级父类设置一个虚方法表 将经常使用的方法抽取出来,不被static private final修饰的方法。在子类中会在父类的虚方法表上添加自己的虚方法。只有父类的虚方法才能被子类继承
继承中的访问:
成员变量:
this调用:就近原则
super调用:直接找父类
就近原则---谁离我近,我就用谁(先在本类中找,如果没有就在父类中找。若出现重名的若要访问本类中的就添加this关键字,若访问父类就加super关键字)
public class test1 {
public static void main(String[] args) {
zi zi = new zi();
zi.zishow();
}
}
class Fu{
String name = "Fu";
}
class zi extends Fu{
String name = "zi";
public void zishow(){
System.out.println(name);//zi
System.out.println(this.name);//zi
System.out.println(super.name);//fu
}
}
成员方法:
直接调用满足就近原则:谁离我近,我就用谁
public class Test2 {
public static void main(String[] args) {
S s = new S();
s.test();
}
}
class P{
public void eat(){
System.out.println("eat p");
}
public void sleep(){
System.out.println("sleep");}
}
class S extends P{
public void test(){
eat();
super.eat();
}
public void eat(){
System.out.println("eat s");
}
}
构造方法:
- 构造方法不会被子类继承
- 子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
why?
1.子类在初始化时,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
2.子类初始化之前,一定要调用父类构造方法先完成父类数据空间初始化
怎么调用父类构造方法?
1.子类构造方法的第一行语句默认都是:super()-调用父类无参构造,不写也存在,且必须在第一行
2.若想调用父类有参构造,必须手写super进行调用
方法重写:
当父类的方法不能满足子类的需求时,需要进行方法的重写
书写格式:在继承体系中,子类出现了和父类中一模一样的方法申明,就称子类中的这个方法为重写方法
@Override重写注解
@Override 方法重写时写在方法上面,校验子类重写时语法是否正确
加上注解后若有红色波浪线表示语法错误
建议重写方法都加@Override注解,代码优雅安全
子类覆盖了从父类继承的虚方法表中的方法
注:
- 重写方法的名称,形参列表必须与父类一致
- 子类重写父类方法时,访问权限子类必须大于父类
- 子类重写父类方法时,返回值类型子类必须小于等于父类
- 私有方法不能被重写
- 子类不能重写父类的静态方法,若重写会报错
重写方法尽量和父类保持一致
只有能被添加到虚方法表的方法才能被重写
class P{
public void eat(){
System.out.println("eat p");
}
public void sleep(){
System.out.println("sleep");}
}
class S extends P{
public void test(){
eat();
super.eat();
}
public void eat(){
System.out.println("eat s");
}
@Override
public void sleep(){
System.out.println("睡觉觉咯");
}
}
this&super
this | super |
理解为一个变量,表示当前方法调用者的地址值 | 代表父类存储空间 |
this(...)访问本类构造方法\本类其他构造方法(有参构造) | super(...)访问父类构造方法 |