java访问控制权限以及复用类
1、访问控制权限
java访问控制关键字共有:private
default
protected
public
,注其中default
为默认包;
设计访问权限的缘由,大概是由于确保客户端代码不会被篡改,以便提示程序员那些可以访问和修改,那些不能,同时程序的迭代必须保证可以向前迭代,但是可以通过标记为不推荐用法,来提示程序员访问旧的或者使用存在某种问题的方法;
访问权限的关键字及其访问范围:
权限 | private | default | protected | public |
---|---|---|---|---|
本类 | √ | √ | √ | √ |
本包中子类 | √ | √ | √ | |
本包中非子类 | √ | √ | √ | |
非本包子类 | √ | √ | ||
非本包非子类 | √ |
包库单元,包内含有一组类,它们在单一的名字空间之下被组织在一起。
下面看具体实例:
默认包内:
// Anmial 以及test均在默认包内,即未命名包内,也称为 `friendly`
public class Anmial {
int size;
private int length;
protected int width;
public int heignt;
public Anmial(){}
void feat(){
System.out.println("feat");
}
private void run(){
System.out.println("go go go");
}
protected void getHeight(){
System.out.println(heignt);
}
public void getweidth(){
System.out.println(width);
}
}
public class test {
public static void main(String args[]){
Anmial anmial=new Anmial();
System.out.println(anmial.size);
//System.out.println(anmial.dream); //报错
System.out.println(anmial.heignt);
System.out.println(anmial.width);
anmial.feat();
anmial.getHeight();
anmial.getweidth();
//anmial.run();// Error:(12, 15) java: run()可以在Anmial中访问private
}
}
0
0
0
feat
0
0
包内:
package com.anmial;
public class Anmial {
int size;
private int length;
protected int width;
public int heignt;
public Anmial(){}
void feat(){
System.out.println("feat");
}
private void run(){
System.out.println("go go go");
}
protected void getHeight(){
System.out.println(heignt);
}
public void getweidth(){
System.out.println(width);
}
}
package com.test;
import com.anmial.Anmial;
public class test {
public static void main(String args[]){
Anmial anmial=new Anmial();
System.out.println(anmial.size); //报错
//System.out.println(anmial.dream); //报错
System.out.println(anmial.heignt);
System.out.println(anmial.width); //报错
anmial.feat(); //报错
anmial.getHeight(); //报错
anmial.getweidth();
//anmial.run();// Error:(12, 15) java: run()可以在Anmial中访问private
}
}
Error:(9, 34) java: size在com.anmial.Anmial中不是公共的; 无法从外部程序包中对其进行访问
Error:(12, 34) java: width可以在com.anmial.Anmial中访问protected
Error:(13, 15) java: feat()在com.anmial.Anmial中不是公共的; 无法从外部程序包中对其进行访问
Error:(14, 15) java: getHeight()可以在com.anmial.Anmial中访问protected
2、复用类
复用,是java众多引人注目的功能之一;
首先,复用有两种形式,继承和组合,组合:在新类中产生现有类的对象;继承:采用现有类的形式,然后添加新的代码;
组合技术:除了基本类型数据之外,要想在新的类中使用对象,必须将其引用置于新的类中;
例如:
package com.anmial;
public class Anmial {
int size;
private int length;
protected int width;
public int heignt;
public Anmial(){}
void feat(){
System.out.println("feat");
}
}
class test{
public static void main(String args[]){
Anmial anmial=new Anmial();
//要想使用Anmial类,必须1将其引用放到此类中...
int x=12;//但是基本类型可以使用;
anmial.toString();//默认继承自Object类
}
}
另外,每个非基本类型,都含有一个toString()
和equals
方法,这是因为都继承自Object
类,即使构建新类时未声明继承(默认);在使用equals
方法时,要注意进行重写,应为Object
类中对其定义如下:即其,采用的是==
比较运算符进行实现的,大多数情况下,要进行重写;
public boolean equals(Object obj) {
return (this == obj);
}
这是一个重写的equals
方法:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
3、继承
每创建一个类,总是在继承,如果没有显示的表明其所继承的超类,则默认为继承的是object
类;这也就是为什么,每个类都有equals
等方法。。。
继承需要使用extends
关键字;A extends B
表明A继承了B,B是A的超类,同时A的继承了B的所有其访问权限以内的方法和变量;
继承初始化:先看一个例子
使用无参构造方式:
package com.test;
public class grandFather {
public grandFather(){
System.out.println("grandfather constructor start。。。");
}
}
package com.test;
public class father extends grandFather {
public father(){
System.out.println("father constructor start...");
}
}
package com.test;
public class son extends father {
public son(){
System.out.println("son constructor start。。。");
}
}
package com.test;
import com.anmial.Anmial;
public class test {
public static void main(String args[]){
son s=new son();
}
}
grandfather constructor start。。。
father constructor start...
son constructor start。。。
public class son extends father {
public String name;
public son(){
System.out.println("son constructor start。。。");
}
public son(String name) {
this.name = name;
System.out.println("son's name is"+name);
}
}
package com.test;
import com.anmial.Anmial;
public class test {
public static void main(String args[]){
son s=new son("davide");
}
}
从例子可以看出,超类的初始化总是被调用,且在子类的构造器哦之前调用。。。
下面看带有参数的构造器:
package com.test;
public class grandFather {
public String name;
public grandFather(String name){
this.name=name;
System.out.println("grandfather's name is"+name);
}
}
package com.test;
public class father extends grandFather {
public int age;
public father(int age){
super("hello");
this.age=age;
System.out.println("father constructor start...");
}
public father(String name){
super(name);
System.out.println("father's name is"+name);
}
}
package com.test;
public class son extends father {
/*public son(){
System.out.println("son constructor start。。。");
}*/
//会报错。。。
public son(String name) {
super(name);
System.out.println("son's name is"+name);
}
}
即继承一个基类,必须实现:将基类的一个构造器初始化,则程序回报出错误;
3、向上转型
首先,由于继承要确保基类中的方法在其导出包中,均可以使用,因此,说明子类对象同时也属于基类;例如:
public static void main(String args[]){
son s=new son();
father f=new father();
System.out.println(s instanceof father);
System.out.println(s instanceof grandFather);
System.out.println(f instanceof son);
}
true //子类同时也是其基类类型
true//子类同时也是其基类类型
false//但其超类不是其子类类型
暂时只做了解,后面还有向下转型;