解决java中的父类私有成员变量的继承问题

如果父类中属性为私有(private),那么能否被子类继承呢?

答案是不可以。

我们看如下简单代码

class Father {
  private String name;

  public void sayHi() {
    System.out.println("My name is " + this.name);
  }
}
class Son extends Father {}
public class PrivateFieldTest {
  public static void main(String[] args) {
    Father f1 = new Father();
    Son s1 = new Son();
 f1.sayHi();
 s1.sayHi();
  }
}

得到的结果是:

My name is null
My name is null

这里我们使用的都是默认构造函数,子类自动引用父类的默认构造函数。直接构造为null。

这样,Son类继承了Father类的sayHi方法,那么自然,Son的sayHi方法中使用的“name”变量,自然就是Son内部继承自Father的私有变量name了,也就是说私有变量可以被继承?

不是的。

我们再看下一段代码,我们在Son的类中重写一下sayHi方法。

class Father {
  private String name;

  public void sayHi() {
    System.out.println("My name is " + this.name);
  }
}
class Son extends Father {
  public void sayHi() {
    System.out.println("My name is " + this.name);
  }
}
public class PrivateFieldTest {
  public static void main(String[] args) {
    Father f1 = new Father();
    Son s1 = new Son();
    f1.sayHi();
    s1.sayHi();
  }
}

这里,出现了编译错误,即Son类里面并没有继承name.

我们看看错误的原因。

The field Father.name is not visible

可以看见,编译器自动认为,name是属于Father的,Son内并没有继承。

那为什么第一段代码中,可以使用sayHi方法得到数据呢?

实际上,这样解释比较好:

“子类不能继承父类的私有属性,但如果子类中公有的方法影响到了父类的私有属性,那么私有属性是能够被子类使用的。”

这句话听起来很拗口,但是实际情况确实也很拗口。

看如下代码

class Father {
  private String name;

  public void setName(String name) {
    this.name = name;
  }
  public void sayHi() {
    System.out.println("My name is " + name);
  }
}
class Son extends Father {}
public class PrivateFieldTest {
  public static void main(String[] args) {
    Father f1 = new Father();
    Son s1 = new Son();
    f1.sayHi();
    s1.sayHi();
    System.out.println();
    f1.setName("Sam");
    f1.sayHi();
    s1.sayHi();
    System.out.println();
    s1.setName("Tom");
    f1.sayHi();
    s1.sayHi();
  }
}

运行结果是

My name is null
My name is null
My name is Sam
My name is null
My name is Sam
My name is Tom

第一段结果,没有变化。

第二段结果,对应的是我们使用setName方法改变了f1的name,所以f1对应的sayHi结果变成了Sam。

第三段结果,对应的是我们使用setName方法改变了s1的name,所以s1对应的sayHi结果变成了Tom。

由此我们可以看到,虽然子类不能继承父类私有变量,但是还是可以通过公有方法使用私有变量。只是重写函数的时候可能比较麻烦,所以要活用super。

补充:Java子类访问父类的私有成员变量

子类会继承父类所有的属性和方法。

但是根据不同的权限标识符,子类不可见父类的私有变量,但可以通过父类的公共方法访问私有变量

所以对于重名变量,子类和父类都各有一份。

对于子类和父类中重名的方法,则为重写。即子类重写了父类的方法,用于多态。

同一个类中函数的签名不同,则为方法的重载。函数的签名为函数名+参数列表,与返回值无关。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • java 利用反射获取内部类静态成员变量的值操作

    昨晚,一同事问到我,怎么利用java反射解析内部类静态成员变量的值,于是顺手写下了. 废话不多说,直接上代码! 待解析类结构如下: /** * @Author changle * @Time 17/6/13. * @Desc to do */ public class Goods { static class apple{ public static String version = "iphone6s[是手机不是吃的苹果]"; public static String date =

  • java创建子类对象设置并调用父类的变量操作

    通过子类调用父类的变量,有两种方法: 1.把父类的变量设置成public: package triangle.opengl.wlz.stu.childusefathervariable; import android.util.Log; public class BasePublicVariable { private String TAG = getClass().getName(); public int data; public void ptData(){ Log.d(TAG, "ptD

  • Win10系统下配置java环境变量的全过程

    一,配置环境变量步骤 1.右击桌面上的"此电脑"图标,选择属性. 2.选择高级系统设置 3.单击环境变量 4.单击系统变量中的新建 5.在变量名中输入JAVA_HOME 变量值中输入jdk安装路径,系统默认路径为 C:\Program Files\Java\jdk1.8.0_221 6.继续单击系统变量中的新建 7.在变量名中输入CLASSPATH 变量值为 .;%JAVA_HOME%lib;%JAVA_HOME%\lib\tools.jar 注意最前面的"."不能

  • Java如何给变量取合适的命名

    一.变量命名风格 变量命名风格通常会根据不同的变量类型来区分,以Java语言为例,根据变量类型不同有两种命名风格: 1)类成员变量.局部变量 类成员变量.局部变量通常采用驼峰命名风格,如下: String userName; 2)静态成员变量.枚举值.常量 静态成员变量.枚举值.常量通常采用所有字母大写.多个单词以英文下划线连接,如: public static final int MAX_YEARS = 25; ​ // 建议枚举类都以Enum结尾 enum ColorEnum { RED(0

  • Java tomcat环境变量及idea配置解析

    一.下载Tomcat 1.进入官网http://tomcat.apache.org/,选择download,下载所需Tomcat版本. 二,我们解压后到指定目录,然后配置环境变量 1>CATALINA_BASE和CATALINA_HOME,值都是tomact地址目录 2>CLASSPATH,在值后面添加;%CATALINA_HOME%\lib\servlet-api.jar;(PS::这个符号是有的) 3>添加Path值,%CATALINA_HOME%\bin和%CATALINA_HOM

  • 解决java中的父类私有成员变量的继承问题

    如果父类中属性为私有(private),那么能否被子类继承呢? 答案是不可以. 我们看如下简单代码 class Father { private String name; public void sayHi() { System.out.println("My name is " + this.name); } } class Son extends Father {} public class PrivateFieldTest { public static void main(St

  • 解决Java中SimpleDateFormat线程不安全的五种方案

    目录 1.什么是线程不安全? 线程不安全的代码 2.解决方案 ① 将SimpleDateFormat变为局部变量 ② 使用synchronized加锁 ③ 使用Lock加锁 ④ 使用ThreadLocal ⑤ 使用DateTimeFormatter 3.线程不安全原因分析 4.各方案优缺点总结 1.什么是线程不安全? 线程不安全也叫非线程安全,是指多线程执行中,程序的执行结果和预期的结果不符的情况就叫做线程不安全. 线程不安全的代码 SimpleDateFormat 就是一个典型的线程不安全事例

  • 解决Java中OutOfMemoryError的问题

    目前为止,我遇到使用Tomcat有三种情况:第一,使用Eclipse,在Eclipse中配置Tomcat.第二,直接在Tomcat中部署项目.第三将Tomcat安装为windows服务. 在这三种情况下,出现OutOfMemoryError.该怎么解决呢?这里我不得不提我被网上那些不负责任的文章害得很惨.各种设置内存的方法都试了,可就是不起作用.下面我说的这几种方法都是我亲自试验过的,没有问题. 第一种情况:  如图:我用红色框框出来的.其中Xms和Xmx是增加java虚拟机初始堆大小和最大堆大

  • 完美解决Java中的线程安全问题

    给出一个问题,如下: 解决方案如下: public class Demo_5 { public static void main(String[] args) { //创建一个窗口 TicketWindow tw1=new TicketWindow(); //使用三个线程同时启动 Thread t1=new Thread(tw1); Thread t2=new Thread(tw1); Thread t3=new Thread(tw1); t1.start(); t2.start(); t3.s

  • 解决Java中的强制类型转换和二进制表示问题

    1.Java中用补码形式表示 2.第一位正负位,1表示负,0表示正. 3.原码:一个数的二进制表示. 3的原码00000011   -3的 原码 100000114.反码:负数原码按位取反(符号位不变).正数原码本身. 3的反码00000011   -3的反码111111005.补码:正数是原码本身.负数反码加1. 3的补码是00000011  -3的补码是11111101int占4个字节,32位 byte占1个字节,8位 所以强转时会截断.前24位 在内存中表示形式( 注意java中是以补码表

  • 解决Java中由于数据太大自动转换成科学计数法的问题

    1.java后台 (1)使用BigDecimal类 方式一:String str=new BigDecimal(num+"").toString(); 方式二:String str=new BigDecimal(num.toString()).toString(); (2)使用DecimalFormat类 //注意,这种方式是保留几位小数 String str=new DecimalFormat("0.00").format(num); 2.JSP页面 (1)使用j

  • Java中不用第三个变量来互换两个变量的值

    我们先看看使用第三变量的方法.(开胃菜) class Swap{ public static void main(String[] args){ int a = 3; int b = 5; int c; c = a; //把a的值先存到c a = b; //把b存给a b = c; //把存在c的值倒赋给b System.out.println("a="+a); //a==5 System.out.println("b="+b); //b==3 } } 下面是运行结

  • 解决Java中properties文件编码问题

    目录 1.properties文件显示乱码问题 2.读取properties文件乱码 3.Spring boot的@ConfigurationProperties读取properties文件乱码 总结 1.properties文件显示乱码问题 原因是因为properties默认使用ASCII码,就算在文件中填写了中文,再打开后依然会转换成ASCII码的形式.首先确定properties配置文件的编码格式,通常情况下properties的默认编码格式为ISO-8859-1.更改properties

  • 解决Java中的java.io.IOException: Broken pipe问题

    Java 中java.io.IOException: Broken pipe 认识broken pipe pipe是管道的意思,管道里面是数据流,通常是从文件或网络套接字读取的数据. 当该管道从另一端突然关闭时,会发生数据突然中断,即是broken. 对于文件File来说,这可能是文件安装在已断开连接的光盘或远程网络上. 对于socket来说,可能是网络被拔出或另一端的进程崩溃. 在Java中,没有具体的BrokenPipeException. 将此类错误包含在另一个异常,例如java.io.I

  • java中重写父类方法加不加@Override详解

    java重写父类方法加不加@Override 这个是我在刚学习java时遇到的问题,希望能给像我一样的新手学习时带来帮助,如有错误请指正,谢谢! class Father{ public String name; public int age; public Father(){ } public void work(){ System.out.println("盖房子"); } } class Son extends Father{ public int weight; public

随机推荐