Java方法的静态与非静态以及访问控制

构造方法

构造方法是一个与类同名的方法,它主要完成对象的初始化,当该类实例化一个对象时会自动调用构造方法.一个类中必须含有构造方法,但并非强制要求写出,如果没有写出的话Java会自动添加一个无参构造方法以供初始化,该构造方法不包含任何的参数,且方法体为空.

默认构造方法的访问修饰符将会和所在类的访问修饰符保持一致,一旦我们在程序中定义了构造方法,那么该默认方法将会失效.

要调用构造方法,应在创建对象时使用new关键字:


public class Test{
    public Test() {
        
    }
    
    public static void main(String[] args){
        Test x = new Test();
    }
}

值得注意的是,构造方法不允许被staticfinalnative等关键字进行修饰,也没有返回值,且不允许被void修饰,但在使用new关键字调用构造方法的上述实例中,此时构造方法会返回当前类.

构造方法会在初始化对象的过程中被自动执行,一般情况下不能够被直接调用.

构造方法具有无参有参两种形式,在一个类中允许定义多个同名方法,前提是这些方法的参数列表不能够相同,在运行时Java编译器会根据方法签名(参数类型)来判断要调用哪一个方法,这种行为被称为方法的重载,值得注意的是重载必须使参数列表相异,仅仅使访问修饰符或是访问类型不同来重载方法使错误的.


public class Test{
    //无参构造方法
    public Test(){
        
    }
    
    //有参构造方法
    public Test(int x){
        
    }
    
    //重载方法
    public Test(double m, int n){
        
    }
}

静态与非静态

在类中使用static进行修饰的方法被称为静态方法,而此外的方法则被统称非静态方法.

类的静态方法在载入类的同时载入的,会随着定义类被装载入内存.

静态方法既能够被静态方法访问,也能够被非静态方法访问;但非静态方法不可被静态方法访问.静态方法在调用时不需要实例化相应的对象,能够通过类名直接调用,而非静态方法依赖于特定对象,因此在调用它们时需要进行对象的创建.以下是一个简单示例 :


public class Test{
    public static int a;
    public int b;

//  '静态'对象无法访问'非静态'数据
    static{
        a = 1;
//      b = 2;  *报错 - 无法从 static 上下文引用非 static 字段 'b'
    }

    //'静态'对象无法访问'非静态'数据
    public static int getA(){
        return a;
//      return b;  *报错 - 无法从 static 上下文引用非 static 字段 'b'
    }

//  '非静态'对象可以访问'静态'数据
    public int getB(){
        return a;
    }

//  '非静态'对象可以访问'非静态'数据
    public int getC(){
        getB();//'非静态'方法可以调用'非静态'方法
        b = a;
        return b;
    }
}

包(Package)的访问级别控制

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

来自 Runoob.com

包有着与文件目录类似的树形储存方式,同一个包中不允许存在相同的类名,但不同包中没有对类名的严格限制,在有同名的类要进行使用时加上包名以倒置域名的形式进行调用,譬如com.test.testclass,包的多层结构名之间以加以分隔.

包亦允许通过访问权限修饰符进行限定范围:

修饰符 本类-Class 同包-Package 子类(非同包)-Subclass 非子类(非同包)-World
public ✔️ ✔️ ✔️ ✔️
protected ✔️ ✔️ ✔️
private ✔️
默认 ✔️ ✔️

在未加上访问控制修饰符(也称为 package-private)的默认访问级别(Friendly)中,当前类中的方法只能被同一个包中的其它类调用,而不能被其他包中的任何类进行调用,如果要直接调用则需要给包加上public进行修饰.

值得注意的是,protected修饰的方法不能被直接调用,需要进行继承通过子类的对象调用继承而来的方法,子类可以直接访问父类中的private的属性和行为.

关于继承的简单实例:


class Test{}
class subTest extends Test{}   //SubTest为子类,Test为被继承的父类.
class extraTest extends subTest{}   //类的多重继承

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

多个类可以称为子类,单独这个类称为父类超类或者基类.子类可以直接访问父类中的非私有的属性和行为。

通过 extends 关键字让类与类之间产生继承关系。

来自 Runoob.com

❗只有在两个类之间为完全相等的关系时才考虑使用继承,而不是仅仅为了继承一部分功能使用继承.


方法重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

在面向对象原则里,重写意味着可以重写任何现有方法。

来自 Runoob.com

在继承了一个类之后,如果想要调用这个类中的方法,那么就可以使用重写来实现

假设有这样一种情况,我们在类文件testOverride.class之中定义了一个类,其中有一个方法,恰好有另一个类文件Test.class想要调用testOverride.class中的这个方法,这时会发现直接使用Class.Method的形式用不了了.


public class testOverride{
    public int value(){
        int a = 6;
        return a;
    }
}

那么可以先写一个工具类用来作为方法的中转站,先使用extends关键字进行继承,然后打上一个@Override标签提醒我们这是重写的方法,然后直接使用super关键字调用返回值给重写类,就可以把这个值传递到新的类中使用了.


public class Test{
    public static class toolMethod extends testOverride{
    @Override
    public int value(){
        return super.value();
       }
    }
}

在Test类中如果要调用重写过来的新的方法,必须要先创建一个该类的实例对象,再通过这个对象进行引用.


public class Test{
    toolMethod tm = new toolMethod();
    int num = tm.value();
    
    System.out.println(num);
    
    public static class toolMethod extends testOverride{
    @Override
    public int value(){
        return super.value();
       }
    }
}

方法的重写还有许多规则,首先是被重写方法的参数列表必须与原方法完全相同,其次包与重写权限的关系遵循访问修饰符的权限级别且不能越级,private > friendly > protected > public,即父类的权限级别不可小于子类.注意,构造方法不能被重写.


参考文章:

https://blog.csdn.net/qq_39098813/article/details/80341896

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

https://www.runoob.com/w3cnote/java-extends.html

https://www.runoob.com/java/java-package.html

https://www.runoob.com/java/java-methods.html

https://www.runoob.com/java/java-override-overload.html

http://c.biancheng.net/view/976.html

https://stackoverflow.org.cn/questions/27904077

文章链接:https://blog.syrizelink.top/index.php/2023/01/169/
?本博客文章仅用作个人学习/知识分享使用,不保证其正确性以及时效性
✏️部分素材来源于网络,如有侵权请联系我删除
?未经作者同意时,如要转载请务必标明出处
上一篇
下一篇