首页 > 代码库 > java中访问权限修饰符解析
java中访问权限修饰符解析
访问权限控制修饰符:public protected 默认(default) private
this static super
final abstract
其中abstract这个修饰符脾气很大,这个修饰符不能与static private final共存
对于final,表示最终,final修饰变量,那么这个变量第一次被赋值后,就不能被再次赋值,也可以把它理解为常量,注意内存空间里面的常量池...这是方法区里面一块特殊的内存空间...
final修饰类,表示这个类是最终类,也就是说,不能有子类,不能被继承,但是任何一个类,只要不被final修饰,都是可以被继承的,是可以拥有子类的,抽象类也有子类,当一个类被继承时,这个类里面被final修饰的成员,不是不能被继承,是不能被重写,重写方法是子类自身定义一个与父类函数名返回值相同的函数,继承的目的一般是为了让子类的功能更加强大,否则继承就是没有意义的,方法重写其实可以认为是对父类方法的升级(或者功能的升级)...
先来看this和super关键字的区别
public class Test{
public static void main(String[] args){
Cat c=new Cat(); //系统调用无参构造创建对象c
c.eat();
}
}
class Animal{
public void eat(){
System.out.println("动物吃东西");}
}
class Cat extends Animal{
public Cat(){
this.eat();
}
public void eat(){
super.eat();
System.out.println("猫吃鱼");}
}
this.成员方法,表示调用当前类的成员方法,也就是谁, this.成员方法 这个语句在哪个类中,就表示调用哪个类的成员方法,super.成员方法 表示调用父类的成员方法, this.成员方法这个语句在哪个类中,就调用所在的类的父类的成员方法...要想知道调用方法的本质是什么,请看下面我的分析
this.eat();这到底是什么意思呢???这表示调用当前类的成员方法,this表示的主体不确定,谁来调用这个方法,this就代表那个对象,调用成员方法,就是让这个方法发挥作用,而发挥作用的是方法体中的语句,我前面讲过方法插入,也就是说,在哪儿调用方法,就表示在调用方法的语句那儿插入方法体语句,所以
this.eat();的本质是一段代码,把这个语句当成一个整体,这个整体就是表示方法体语句,既然是方法语句,比如System.out.println();这就是一个方法语句,方法语句不能独立存在,方法语句只能依托于成员方法,而成员方法属于类,所以,我们现在也就明白了,该把this.eat();语句摆放在什么位置,只要记住,this.eat()就是几个语句,语句当然是放在成员方法中了(main方法也是成员方法),同样,super.eat()也是放在成员方法中,其本质也是几个独立语句,也必须放在方法体中,但是
super.eat()所在的类必须一定有父类,否则super就没有意义,总而言之,一定要记住方法插入,记住方法调用的本质是什么...当然,如果方法里面还包含其它方法,就要具体事情具体分析,总之,如果方法里面是独立语句...一定要注意...
public Cat(){
this.eat();
}
这是把this.eat();放在Cat类的无参构造方法中,无参构造方法也是一个方法,但是它不同于类的成员方法,类的成员方法可以用类的实例或者类本身去调用,但是构造方法的功能是给类的实例提供初始化,或者简单地说,构造方法的作用是生成对象,可以给对象提供初始值(有参构造),但是调用构造方法的是系统,不是由类来调用,在这里,把this.eat();放到构造方法体内,是没有问题的,因为this.eat();其实就是等效于System.out.println("猫吃鱼");把一个独立语句放在方法体中,是没有任何争议的...同理super.eat();等效于一个独立语句System.out.println("动物吃东西");把一个独立语句放在eat方法体中,也是没有问题的
Cat c=new Cat();
c.eat();
表示利用Cat的空参构造创建对象,然后把这个对象的地址赋值给c,通过c就可以去操作这个对象的成员了,或者更简单的说,上面的语句就是创建对象c,然后用c去调用eat方法,和上面一样,c.eat();表示调用c对象的eat方法,其实就是等效于super.eat();System.out.println("猫吃鱼");这段代码,super.eat();也是一段代码,所以,我们上面说过,调用方法的本质就是一段代码实现功能...
最后输出
动物吃东西
猫吃鱼
动物吃东西
猫吃鱼
this(...);表示调用本类构造方法,super(...);表示调用父类构造方法.
this.成员方法,调用本类的成员方法,也可以调用父类的成员方法(就近原则,重写或者覆盖)
我们当然知道,成员方法需要类或者对象去调用,但是this.成员方法,这里的this不是指代一个类,而是一个对象,同理super.成员方法,这里的super一定指的是一个父类对象...
正确的思路就是:我们想调用方法,如果是非静态,那么就要创建对象,不是创建了对象再去调用方法,而是为了调用某个方法,我才去创建对象,调用方法的本质是:在程序的某个位置插入一段代码块,方法的优点就是封装了一段代码块,想要实现这段代码块的功能,我们不用直接在程序里面写出这段代码,直接调用方法就可以,下面我来举个例子:
public class Test{
public static void main(String[] args){
}
}
我们要打印"你妹",当然,我们可以直接在主方法中添加System.out.println("你妹");语句
但是,我们把这段代码封装到方法里面,因为调用方法真正起作用的是方法里面大括号里面的语句;
不要被方法名这些东西干扰...
System.out.println("你妹");这段语句是真正需要的语句,因此,这段语句就是方法的执行语句,
写出一个方法
public void print(){System.out.println("你妹");}
这个方法就封装好了,于是我们要调用这个方法,调用方法只能用类名调用或者对象调用,但是这个方法是非静态方法,只能通过对象来调用,于是我们需要对象,创建对象需要类,因此,需要把这个方法放在一个类中...我们可以直接放在Test类中,于是
public class Test{
public static void main(String[] args){
}
public void print(){System.out.println("你妹");}
}
注意方法与方法之间是并列关系,方法不能包含方法,因为他们地位平等,main方法也是一样,既然print方法位于Test类中,那么就是Test类的方法,调用该方法使用Test类的对象,也就是Test类的对象.print方法,但是调用方法以及创建对象(系统调用构造方法)都是一些独立的代码块(必须放在main方法中),因此
public class Test{
public static void main(String[] args){
Test t=new Test();
t.print();
}
public void print(){System.out.println("你妹");}
}
super.成员方法,调用父类成员方法.
this.成员变量,调用本类的成员变量,也可以调用父类成员变量.
super.成员变量,调用父类成员变量.
final修饰方法,方法不能被重写,意思就是说,如果父类中定义了一个final方法,那么子类只能原原本本的继承这个方法,java禁止在子类中重新定义这个方法,你要是定义,编译就会出错,所以不可能在子类重新定义这个方法,这时候,也就不存在方法重写覆盖,或者两个方法谁占据上风的问题了...
看下面的代码
public class Test{
public static void main(String[] args){
Cat c=new Cat(); //系统调用无参构造创建对象c
c.eat();
}
}
class Animal{
public final void eat(){
System.out.println("动物吃东西");}
}
class Cat extends Animal{
public Cat(){
this.eat();
}
}
上面已经把Animal类的eat方法设定为final,那么在Cat类里面将不能定义eat方法,由于Cat类并没有另外设定自己的成员方法,所以Cat类中只有一个成员方法,就是从Animal中继承的eat方法...
当然,final修饰的类不能被继承,但是final修饰的属性和方法却可以被继承
要想属性和方法不被继承,可以使用private修饰,也就是说,private修饰的成员不能被子类继承...
看下面的错误代码
public class Test{
public static void main(String[] args){
Cat c=new Cat(); //系统调用无参构造创建对象c
c.eat();
}
}
class Animal{
private void eat(){
System.out.println("动物吃东西");}
}
class Cat extends Animal{
}
Amimal中,eat方法设置为私有,Cat类根本无法继承到eat方法,Cat类没有eat方法, c.eat();使用c去调用一个根本不存在的eat方法,当然会出错...
再看下面的代码
public class Test{
public static void main(String[] args){
Cat c=new Cat(); //系统调用无参构造创建对象c
c.eat();
}
}
class Animal{
private void eat(){
System.out.println("动物吃东西");}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");}
}
这段代码可以编译通过,为什么呢,因为Cat类根本没有继承Animal类的eat方法,所以,Cat类只有一个public void eat(){
System.out.println("猫吃鱼");}方法,不存在从父类继承的被覆盖的eat方法...
再看下面的问题代码
public class Test{
public static void main(String[] args){
Animal c=new Cat(); //系统调用无参构造创建对象c
c.eat();
}
}
class Animal{
private void eat(){
System.out.println("动物吃东西");}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");}
}
这段代码为什么出错呢??? Animal c=new Cat(); c.eat();
Animal c=new Cat();这是父类引用指向子类对象,也就是向上转型,为什么要这么写,Animal c本来应该操作Animal 类的对象的成员,实际上Animal c=new Cat();这样写的前提是Cat类的对象中有从Animal类中继承的元素,Animal c所能操作的是Cat类从Animal中继承的元素,但是Cat类并没有继承Animal类的eat方法,所以c.eat();想去操作继承的eat方法,根本是不可能,因为eat方法根本没有继承...
java中访问权限修饰符解析