- Java的访问控制修饰符有哪些?各有什么访问权限?请对照第7页ppt的表格分别写程序验证。
答:访问控制修饰符:public,protected,private。访问权限首先看类前的修饰符,当类的修饰符为public时,则类可以被所有的类所访问(可以import);当为默认时,则只能为包中的类所访问。在此前提下,再看属性和方法前的修饰符。类前修饰符为public时,当属性和方法前的修饰符为public时,则该属性可以被所有类访问;当属性和方法前为protected修饰时,对于类定义而言,可以被同包中的类和所有子类访问(子类和父类可以不在同一一个包中),也就是B+C范围,但对于对象而言,只能被同一个包的类对象所访问,也就是B的范围;当为默认时,只能被同包中的类所访问( 比protected访问权限小) ;当为private时,只能被本类内部所访问。
**同一包中:public类
public属性的访问
public class FighterPlane {
public String name;
public int missileNum;
public void fire(){
if (missi1eNum>0){
System. out . print1n("now fire a missile!");missileNum -= 1;
}
else{
System. out . print1n("No missile left !");
}
}
}
pub1ic class RunPIane {
public static void main(String args[]){
FighterPlane fp = new FighterPlane();
fp.name = "cjr";
fp. missileNum = 6;
fp. fire();
}
}
protected属性的访问protected属性具有包访问权限,可以被同一包中所有权限访问
public class FighterPlane {
protected String name;
protected int missileNum;
protected void fire(){
if (missi1eNum>0){
System. out . print1n("now fire a missile!");missileNum -= 1;
}
else{
System. out . print1n("No missile left !");
}
}
}
pub1ic class RunPIane {
public static void main(String args[]){
FighterPlane fp = new FighterPlane();
fp.name = "cjr";
fp. missileNum = 6;
fp. fire();
}
}
在不同的包中,protected属性的访问:不能通过对象引用fp来访问不在同一包的类的protected属性和方法
package com. resource ;
pub1ic class FighterPlane {
protected String name ;
protected int mi ssileNum;
pub1ic void fire(){
if(x=missileNum>0){
System. out . print1n("now fire a missile !");
missileNum -= 1;
}
else{
System. out. print1n("No missile left !");
}
}
}
```java
package com. run;
import com. resource. FighterPlane;
public class RunPlane {
pub1ic static void main(String args[]){
FighterPlane fp = new FighterPlane();
***fp.name ="cjr";
fp. missileNum = 6;***
fp. fire();
}
}
不同包继承关系,public类属性访问:子类的类定义中可以访问父亲类的protected属性和方法,无论在不在同一包中
package com. resource ;
pub1ic class FighterPlane {
protected String name ;
protected int mi ssileNum;
pub1ic void fire(){
if (missileNum>8){
System. out . print1n("now fire a missile !");missileNum -= 1;
}
else{
Svstem ouut. nrint1n("No missile left ");
}
}
}
package com. run;
import com. resource.FighterPlane;
public class RunPlane extends FighterPlane{
pub1ic static void main(String args[ ]){
RunPlane fp = new RunPlane( ) ;
fp. init();
fp. fire();
}
private void init(){
name = "cjr";
missileNum = 6;
}
}
不同包中,public类的private属性
package com. resource;
public class FighterPlane{
private String name ;
private int missil eNum;
private static FighterPlane fp;
private FighterPlane(String_ name, int_ missileNum{
name =_ name ;
missi1eNum =_ _missileNum;
}
public static FighterP1ane getInstance(String_ name,int_ missileNum){
if (fp==null){
fp = new FighterPlane(_ name,. missi1eNum);
}
return fp;
}
}
package com. run;
import com. resource.*;
public class RunPlane{
public static void main(String args[]){
FighterPlane fp;
// fp = new FighterPlane; / /不允许调用构造器,无法创建对象
fp=FighterPlane . getInstance("cjr",6);/ /保证该类只能有一个实例对象
}
}
2.子类对于从父类继承的哪些属性与方法是可见的?请分别写程序进行验证。
答:子类对于从父类继承的public,protected属性与方法是可见的.
子类可以直接访问父类的protected属性和方法
classPlane{
protected String name ;
public void setName(String_ name){
name =_ name ;
}
public String getName(){
return name ;
}
}
class FighterPlane extends Plane{
private int missileNum ;
public void setNum(int_ _missileNum){
missileNum =_ missileNum;
}
public void fire(){
missileNum -= 1;
}
}
class Run{
public static void main(String[] args){
FighterPlane p = new FighterPlane( );
p.name = "cjr";
p. setName("cqq");
System. out . println(p. getName());
p. fire();
}
}
子类不能直接访问父类的private属性和方法,可以调用父类公共的方法来简介访问私有属性
classPlane{
protected String name ;
public void setName(String_ name){
name =_ name ;
}
public String getName(){
return name ;
}
}
class FighterPlane extends Plane{
private int missileNum ;
public void setNum(int_ _missileNum){
missileNum =_ missileNum;
}
public void fire(){
missileNum -= 1;
}
}
class Run{
public static void main(String[] args){
FighterPlane p = new FighterPlane( );
//p.name = "cjr";
p. setName("cqq");
System. out . println(p. getName());
p. fire();
}
}
3.什么是组合?有什么作用?请举例说明。
答:组合用来表示拥有关系。当我们创建一个A类对象时,也会随着产生一个B类对象;当A类对象消亡时,它所包含的B类的对象随之消亡,就是说两个生命周期时一致的。
面向对象程序设计其所以能比面向过程设计有较大影响力,其中的一个关键是具有“高内聚,松耦合”的特点,这个特点就是通过封装与组合技术的综合运用来实现的。封装是利用访问控制符来实现的,而组合则通过对象内部的属性引用来实现。例如
class FighterPlane{
String name;
int missileNum;
public FighterPlane(Stringname, int miss_ileNum){
name _ name;
missileNum =missileNum ;
}
public void fire( ){
if (missileNum> 0){
System.out.println("now fire a missile!");
missileNum-= 1 ;
}
else{
System.out println("No missile left !");}
}
}
}
class A {
FighterPlane fp;
public A(F ighterPlane fpp){
this.fp= fpp;
//A对象中拥有了FighterPlane对象的引用
}
public void invoke(){
//A对象发送消息给FighterPlane的对象
System. out. println(fp, name);
}
}
public class Run{
publie static void main(String[ ] args){
FighterPlane ftp = new FighterPlane("cjr",10);
//产生A对象,并将ftp作为对象引用传入
A a=new A(ftp);
//发送消息,产生调用关系a. invoke( );
a.invoke();
}
}
引用fp就将A对象和FighterPlane对象组合起来: A对象和FighterPlane对象虽然在内存当中是两个对象,但是由于A中拥有FighterPlane 对象的引用,就可以把A对象看成是由FighterPlane对象组合而成的。
组合会使对象之间的耦合性较为松散,因为A对象通过引用向FighterPlane对象发送消息从而使A与FighterPlane产生相互关联,这种联系是建立在FighterPlane的授权基础上的,**FighterPlane对象私有的属性和私有方法A是无法访问的。**因而,消息和内部私有方法之间就没有直接的联系,这就为阻断变化在软件系统内的传播提供了可能。
4.什么是重载?有什么作用?请举例说明。
答:重载就是,在类中定义了多个不同名的不同内容参数的成员方法。(方法名称相同,参数类型或者个数不同。ps:返回类型不同的方法不是重载。)
定义端:使用相同的方法名(一个方法)来表示功能相同的方法(多个)方法
调用端:在调用时,可以使用相同的的名字来实现不同的功能。
大大简化了类调用者的代码。
例:
两个方法的实现代码如下:
public AudioClip getAudioCliip(URL url) {
.....;//真正的实现代码
}
public AudioClip getAudioCl ip(URL url,String name) {
.......//其他代码
//通过更新构造一个新的URL对象,之后调用上面的同名方法
return getAudioCl ip( new URL(url, name));
它们的简要实现代码如下:
public boolean addAll(Collectionc) {
return addAll(size, c);
//size是当前集合所拥有的对象引用数量,此方法调用下面的方法
}
//类似数组下标,每个对象引用在集合结构当中都拥有index
public boolean addAll( int index, Collectionc) {
....... //真正的实现代码
}
5.什么是覆盖?有什么作用?请举例说明。
答:子类对父类参数相同,返回类型相同的同名方法重新定义【如果子类定义的方法与父类名称相同(大小写完全匹配),但参数名称不同或个数不同不叫覆盖叫重载】。
ps:
1.子类方法覆盖父类方法,子类的访问修饰符权限应等于或大于父类。
2.同名的static方法和非static方法不能相互覆盖 。
class Parent{
public int getScore(){
return 3;
}
public String getCountryName(){
return " China";
}
class Son extends Parent {
public int getScore(){
return 4;
}
}
public class RunSon{
public static void main( String args[]){
Son s = new Son();
System, out. println(s. getScore());
System. out, println( s. getCountryName());
}
}