java权限修饰符作用及用法
Java权限修饰符作用及用法
本材料由武汉理工大学软件工程1004班刘礼钊编写,鉴于接触这些知识点尚且不是很久,故该文档可能存在少数疑点,欢迎大家指正。本人QQ:1115150984
1、private:私有权限。
在类中定义方法或对象之前加上private修饰符之后,该方法(对象)将成为类的私有成员。于是该方法(对象)只能被当前包的当前类中的成员方法调用,而异包和同包的任何不同类(不论是否是当前类的子类)则都不能对其进行调用,该类被继承后其private方法(对象)在子类中不可访问。如:
public class test
{
int in;
private int privt;
protected int protect;
public in t publc;
test(int i,int pr,int pro,int pl)
{
in=i;
privt=pr;
protect=pro;
publc=pl;
}
public void show()
{
System.out.print("in="+in+"\nprivt="+privt+"\nprotect="+pro tect+"\npublc="+publc+"\n");
}
}
public class mainprogram
{
public static void main(String[] args)
{
test tst;
tst=new test(23,34,45,56);
tst.show();
System.out.println();
tst.in=12;//可修改
tst.show();
System.out.println();
//tst.privt=9;//添加进来则会编译时报错!
tst.protect=10;//可修改
tst.show();
System.out.println();
tst.publc=11;//可修改
tst.show();
}
}
结果截图:
2、protected:保护权限。
在定义类方法或成员对象时加上protceted修饰符后,该方法(对象)将成为受保护成员。受保护方法(对象)可以被当前包中的任何类访问,也可以被它的任何包中的子类访问。
3、public:公开权限。
在定义类方法或成员对象时加上public修饰符后,该方法(对象)将成为公开成员。公开方法(对象)将会允许任何包中的任何类
对其进行访问。
注意:private、protected、public权限修饰符在继承时都是完全继承的,只是由于权限的限制,部分成员对象和方法不能被调用,故而有些材料上有不继承之类的说法。
4、static:静态标识符。
定义方法或变量时加上static后将成为静态成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。方法和变量都可以被声明为static,static 成员的最常见的例子是main()。因为在程序开始执行时必须调用main(),所以它被声明为static。另外,System.out.println()函数中的out也是被声明为static的,所以调用时我们不必创建相应的对象就可以直接访问。申明为static的变量实际上就是一个全局变量,无论创建多少个对象,相应的static变量只有一个,这个变量时共享的,当一个对象对这个static变量进行了修改,那么其他对象获取这个变量的值时得到的就是修改后的值。声明为static的方法有以下几条限制:
◆它们仅能调用其他的static 方法。
◆它们只能访问static 数据。
◆它们不能以任何方式引用this 或super。例:
package com.birdme;
public class UseStatic
{ /** * @param args */
private static int s;
public UseStatic()
{ System.out.println("Create new Class"); }
static{ System.out.println("static block initialized");}
public int getStatic(){ return s; }
public void setStatic(int i){ s=i; }
public static void main(String[] args)
{ // TODO Auto-generated method stub
UseStatic classA=new UseStatic();
UseStatic classB=new UseStatic();
System.out.println("classA.s="+classA.getStatic()+";classB.s= "+classB.getStatic());
classA.setStatic(10);
System.out.println("classA.s="+classA.getStatic()+";classB.s=
"+classB.getStatic());
classB.setStatic(classB.getStatic()+10);
System.out.println("classA.s="+classA.getStatic()+";classB.s=
"+classB.getStatic());
}
}
下面是该程序的输出:
从结果可以看出类中static 块程序是在类被装载的时候开始执行。而不是在创建对象的时候执行。
5、super:超类,即当前类的父类。
在构造一个子类的实例时,首先得调用父类的构造函数。这时就可以在子类构造函数的第一行添加上一句super()语句。当然,如果父类的构造函数需要传递参数你也可以根据需要改写成super(param1,param2,…)的形式。另外,当子类中对父类的方法进行了覆盖,而你又想调用父类的那个方法,你就可以通过super.function()的方法实现调用。
例:
class Person{
public int c;
private String name;
private int age;
protected void setName(String name)
{
https://www.360docs.net/doc/3a13791763.html,=name;
}
protected void setAge(int age)
{
this.age=age;
}
protected void print()
{
System.out.println("Name="+name+" Age="+age);
}
}
public class DemoSuper extends Person
{
public void print()
{
System.out.println("DemoSuper:");
super.print();
}
public static void main(String[] args)
{
DemoSuper ds=new DemoSuper();
ds.setName("kevin");
ds.setAge(22);
ds.print();
}
}
运行结构截图:
6、this:对当前类的引用。
其实this主要有三种用法:
(a)表示对当前对象的引用;
(b)表示用类的成员变量,而非函数参数,注意在函数参数和成员
变量同名时进行区分!其实这是第一种用法的特例,比较常用,所以拿出来强调一下;
(c)用于在构造方法中引用满足指定参数类型的构造器(其实也就
是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始。
还有就是注意:this不能用在static方法中!所以甚至有人给static 方法的定义就是:没有this的方法!虽然夸张,但是却充分说明this不能在static方法中使用!
例1:
package test;
public class ThisTest
{
private int i=0; //第一个构造器:有一个int型形参
ThisTest(int i)
{
this.i=i+1;
//此时this表示引用成员变量i,而非函数参数i
System.out.println("Int constructor i——this.i: "+i+"——
"+this.i);
System.out.println("i-1:"+(i-1)+"this.i+1:"+(this.i+1));
//从两个输出结果充分证明了i和this.i是不一样的!
} // 第二个构造器:有一个String型形参
ThisTest(String s)
{
System.out.println("String constructor: "+s);
}
// 第三个构造器:有一个int型形参和一个String型形参ThisTest(int i,String s)
{
this(s);//this调用第二个构造器
//this(i); /*此处不能用,因为其他任何方法都不能调用构造器,只有构造方法能调用他。但是必须注意:就算是构造方法调用构造器,也必须为于其第一行,构造方法也只能调用一个且仅一次构造器!*/
this.i=i++;//this以引用该类的成员变量
System.out.println("Int constructor: "+i+"\n"+"String constructor: "+s);
}
public ThisTest increment()
{
this.i++;
return this;
//返回的是当前的对象,该对象属于(ThisTest)
}
public static void main(String[] args)
{
ThisTest tt0=new ThisTest(10);
ThisTest tt1=new ThisTest("ok");
ThisTest tt2=new ThisTest(20,"ok again!");
System.out.println(tt0.increment().increment().increment().i);
//tt0.increment()返回一个在tt0基础上i++的ThisTest对
象,接着又返回在上面返回的对象基础上i++的ThisTest对
象!
}
}
运行结果截图:
例2:
public class DemoThis
{
private String name;
private int age;
DemoThis(String name,int age)
{
setName(name);//您可以加上this来调用方法,像这样:
//this.setName(name);但这并不是必须的
setAge(age);
this.print();
}
public void setName(String name)
{
https://www.360docs.net/doc/3a13791763.html,=name;//此处必须指明您要引用成员变量
}
public void setAge(int age)
{
this.age=age;
}
public void print()
{
System.out.println("Name="+name+"Age="+age);//在此行中并不需要用this,因为没有回导致混淆的东西
}
public static void main(String[] args)
{
DemoThis dt=new DemoThis("Kevin",22);
}
}
运行结果截图:
7、final:final即最终的意思。
(a)如果将方法声明为final,那就说明你已经知道这个方法提供的
功能已经满足你要求,不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。另外有一种被称为inline的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那么你的调用主体代码便会迅速膨胀,可能反而
会影响效率,所以你要慎用final进行方法定义。
(b)当你将final用于类的定义时,你就需要仔细考虑,因为一个final 类是无法被任何类继承的,于是有人戏称被final了的类为“断子绝孙类”。那也就意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要进行修改或扩展。对于final 类中的成员,你可以定义其为final,也可以不是final。而对于方法,由于所属类为final的关系,自然也就成了final型的。你也可以明确的给final类中的方法加上一个final,但这显然没有意义。例:
final class Final
{
final String str="final Data";
public String str1="non final data";
final public void print()
{System.out.println("final method.");}
public void what()
{System.out.println(str+"n"+str1);}
}
public class FinalDemo
{//extends final 无法继承
public static void main(String[] args)
{
Final f=new Final();
f.what();
f.print();
}
}
结果截图:
(c)当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,儿对于变量来说其引用不可再变。其初始化可以在两个地方,一是其定义处,也就是说在final变量定义时直接给其赋值,二是在构造函数中。这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义
时给了值,又在构造函数中给了另外的值。例:
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class Bat
{
final PI=3.14;//在定义时便给之值
final int i;//因为要在狗仔函数中进行初始化,所以此处不可给值
final List list;//此变量也与上面的一样
Bat()
{
i=100;
list=new LinkedList();
}
Bat(int ii,List l)
{
i=ii;
list=l;
}
public static void main(String[] args)
{
Bat b=new Bat();
b.list.add(new Bat());
//b.i=25;
//b.list=new ArrayList();
System.out.println("I="+b.i+"ListType:"+b.list.getClass());
b=new Bat(23,new AarrayList());
b.list.add(new Bat());
System.out.println("I="+b.i+"ListType:"+b.list.getClass());
}
}
另外方法中的内部类在用到方法中的参变量时,此变量也必须声明为final才可使用,如下代码所示:
public class INClass
{
void innerClass(final String str)
{
class IClass
{
IClass()
{System.out.println(str);}
}
IClass ic=new IClass();
}
public static void main(String[] args)
{
INClass inc=new INClass();
inc.innerClass("Hello");
}
}
8、abstract:抽象。
abstract 修饰的CLASS是抽象类。抽象类(abstract class)可以有抽象方法,也可以有具体是方法,抽象类只能支持单继承。抽象类主要需要记住以下几项要点:
(1)抽象类不能被实例化.
(2)抽象类有构造器,且他的构造在他的子类被实例化时被调
用的顺序和普通类调用的顺序是一样的(先父后子).
(3)抽象类内部的方法可以不是抽象方法,也就是说抽象类内
部可以有具体的方法.
(4)抽象类的抽象方法属于一种不完整的方法,只含有声明和
定义,没有方法主体.
(5)如果抽象的某个子类是普通类(非abstract类型的类),那么
该子类必须Override抽象类中所有的抽象方法.
(6)抽象类的子类也是抽象类的话,那么该子类既可以
Override父类中的方法,也可以不Override父类中的方法.
(7)普通类中不能定义抽象方法.
(8)static不能修饰抽象方法
备注:为了方便理解,所谓的普通是指如下形式定义的类
public class X{} 或class A XX{}
9、interface:接口。
接口可以有抽象的方法,不存在具体的方法,接口可以多继承(多实现)。接口主要有几下要点:
(1)JAVA接口没有构造器
(2)JAVA接口中的成员变量必须显式赋初始值
(3)JAVA接口中的方法没有方法体,定义形式是[public][abstract]
方法类型[方法名]([参数列表]);
(4)JAVA接口的定义形式如下:
* [修饰符] interface 接口名[extends 父接口名列表]{
[public] [static] [final] 数据类型成员变量名=变量值;
[public][abstract] 方法类型方法名([参数列表]);
}
(5)JAVA接口中的成员变量默认为public static final类型的,如
inti=1; 相当于是public static final inti=1;
* JAVA接口中常量默认是加了public static final 意味着:公用,共用,并且不可更改。
(6)JAVA接口是不能被实例化的
(7)JAVA接口中的方法不能用static修饰
(8)JAVA接口中的所有的方法都是抽象的,不管有没abstract 修饰,且默认是
public abstract 方法类型方法名([参数列表]);
(9)JAVA接口中子接口可以继承多个父接口,子类可以实现多个父接口