访问权限
首先,我们来谈以下访问权限存在的原因。
第一个原因:让客户端程序无法触及他们不应该触及的部分。
(举例:就像我们创建一个 “人” 类,他的属性有名字(String name) 那么每一个人的名字都是父母起好的,我们其他人只能有访问的权限,不该有更改的权限。)
第二个原因:允许库设计者可以改变类内部的工作方式,而不用担心影响到客户端程序员。
(举例:假如库设计者写的一个X类中有很多方法,现在设计者要优化方法的执行过程,只要这个方法客户端程序员是只能调用但无法修改的,那么我改变这个方法的执行过程是不会影响到它的使用,因为最后的结果都一样。)
那么在Java中有哪些控制权限的关键字呢?
public ,private , protected
public(共有的):public表示紧随其后的元素对任何人都是可用的。
private(私有的):这个关键字除了类创建者和内部方法之外的任何人,都不能访问。
protected(继承可访问的):这个关键字与默认访问权限相当,同包路径下可以访问,但不同包非子类不能访问。
默认访问权限:当没有任何关键字指定访问权限时,它才会发挥作用。这种权限通常被称为包访问权限,在这种权限下,类可以访问在同一个包中的其他类的成员,但是在包之外,这些成员则如同被private了一样。
什么是类构造器?
类构造器,就是对其成员的初始化方法。
我们现在假设有一个People类,成语变量有 name 和 age。
如果我们什么都不写,那么在Java中会调用它的默认方法(无参构造器)。就会给他们赋所属类型的默认值(具体默认值可以参考我的基础类型博客)。
举例:
People类
public class People {
private String name; //名字
private int age; //年龄
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
test测试:
public static void main(String[] args) {
People p = new People();
System.out.println(p.getAge());
System.out.println(p.getName());
}
运行结果:
那么如果我们想要在创建一个People对象的时候就给他赋好一个名字和年龄呢?如果按照以前的话,我们会写一个set方法,去挨个赋值,现在我们可以只用一个构造器就可以了。
我们把People 类改为以下的代码。
public class People {
private String name; //名字
private int age; //年龄
public People(String name,int age){ //有参构造器
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
那么我们在创建一个People对象时,就必须给定名字和年龄的参数了。
public class test {
public static void main(String[] args) {
People p = new People("张三",18);
System.out.println(p.getAge());
System.out.println(p.getName());
}
}
运行结果:
在这个构造器里,我们运用了this关键字,this到底是什么意思呢???
我们就用这个方法中的this来举例,
this表示的就是当前对象。那么可能就会有人问,它怎么知道它表示的时那个对象???我只是调用了这个类的方法而已,我传入的只是它的方法需要的参数,没有传入对象啊。
在Java中调用一个对象的方法,会首先把当前对象传进去。所以this关键字才能找到调用方法的对象。
能不能写两个构造器呢?一个有参一个无参,起什么名字呢?
public class People {
private String name; //名字
private int age; //年龄
public People(){ //无参构造器
}
public People(String name,int age){ //有参构造器
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
test测试:
public static void main(String[] args) {
People p1 = new People();
System.out.println(p1.getAge());
System.out.println(p1.getName());
People p2 = new People();
System.out.println(p2.getAge());
System.out.println(p2.getName());
}
结果
大家看到,我们可以创建两个构造器,但这个两个构造器的区别就是在于参数列表的不同,方法名是一模一样的。
这样的方法,我们叫做,方法重载
方法重载:方法名相同,参数列表不同 。
以上两个构造器的方法,皆为方法重载。
那么我们在类中的构造方法是否可以相互调用呢?
假如,People 的新对象p1没有传入参数,我们默认名字是 “李四” 年龄 18 岁。就相当与把 “李四” ,18 这两个参数传入了另一个构造器。
public class People {
private String name; //名字
private int age; //年龄
public People(int age){
this.age = age;
}
public People(String name,int age){
this.name = name;
this.age = age;
}
public People(){
this("李四",18); //调用另一个构造器
this(18); //调用其它构造器,
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
大家可以发现,我们如果在一个构造器里调用一个构造器是可以的,但不能调用两个,并且,必须把调用构造器写在第一行的位置。
并且,构造器无法相互调用,这相当于自己不断的调用构造方法,是一个死循环。
静态
静态的关键字:static
常量用 final 关键字修饰
我们先来谈谈最简单的静态常量。假如,我们定义了一个数组,我们每创造一个对象,就往数组里放一个值。一开始我们把数组的初始大小定义为10。
那么后面发现这个10太小了,不够用,或者,我们需要不断的用10这个初始定义数组的大小,我们要不断的写10。
如果更改代码的话,我们需要找到利用初始定义数组大小的那么方法,再去改。这极其的麻烦。那么我们定义一个静态常量,就用来表示数组的初始大小。
private static final int INIT = 10;
那么后面我们要用这个10的话,直接写INIT就好了,如果我们要更改大小,就只用更改INIT的值就好。
静态方法。我相信很多人在初期写代码的时候都遇到过,静态方法不能调用非静态方法 这一问题。
为什么不能调用?什么是静态方法???现在我们就来谈谈。
所谓静态方法,就是不含this的方法。也就是说,参数传入方法的时是不会默认传入对象的,他不会知道是哪个对象调用的。它不含this,他就无法指定对象,没有对象就不能调用非静态方法,因为非静态方法需要对象去调用。
那么静态方法就与对象无关,它只于类有关. 所以调用静态方法时,我们可以用类调用。不需要创建对象,再去调用。
举个例子:我们在调用 Scanner 类中的 nextInt 方法时,我们需要创建一个对象.而我们调用输出数组的Arrays.CopyOf()方法时,不需要对象.
总结
访问权限:
Public: 公共访问,跨包也可以访问,但要import导入
private: 私有的,只有自己能访问
protect: 继承访问,同包路径以及所继承的类可以访问.
默认权限(什么限制都没有): 同包下可以访问.
类构造器
类构造器就是初始化方法.
一个类可以有多个构造器,但必须是重载方法.
构造器可以调用另一个构造器,但必须写在第一行,并且只能调用一个构造器.并且用this语句调用.
重载方法
在同一个类中 方法名相同,参数列表不同的方法叫做重载方法。
this
表示当前对象,非静态方法Java会自动传入对象名,
成员方法里包含隐含的this。
静态
与对象无关,与类有关系,
静态方法不能提供this引用,成员方法里面包含隐含的this,所以静态方法不能直接调用非静态方法,必须通过对象调用.