Java编程复用类代码详解
作者:iaiti 发布时间:2021-09-13 10:06:34
本文研究的主要是Java编程中的复用类,那么到底复用类是什么东西,又有什么用法,下面具体介绍。
看了老罗罗升阳的专访,情不自禁地佩服,很年轻,我之前以为和罗永浩一个级别的年龄,也是见过的不是初高中编程的一位大牛之一,专访之后,发现老罗也是一步一个脚印的人。别说什么难做,做不了,你根本就没去尝试,也没有去坚持。
If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but
whatever you do,you have to keep moving forward——Martin Luther King.
复用类这标题刚开始很难懂,后面专门去看了书的英文原版,其实标题是reusing classes,重新使用类,其实复用就是“利用现成的东西”的意思,其实实现的两种方法就是java中经常听到的——组合和继承。
(1)组合
has-a的作用。
public class TV {
Show show;
public String toString(){
return "showgirl";
}
}
class Show{
}
提一下toString方法,当你需要String而你是一个对象的时候,编译器会调用对象的toString方法。
TV里有Show,现在的show没有初始化,为null,不能调用show的方法。
组合的作用强大,以面向对象看,假如你在造一个Car类,那么你可以用组合轻易的将Glass,Light,Engine等等的Car这些部件组合起来。
(2)继承
is-a
package com.myown.iaiti;
public class Father {
public int i;
void get(){
System.out.println("father");
}
}
package son;
import com.myown.iaiti.*;
public class Son extends Father{
Father f = new Father();
int j = f.i;
Son son = new Son();
son.get();
}
public void get(){
super.get();
System.out.println("son");
}
}
这里有个包访问权限的问题,假如没有加public的时候,默认是包内成员访问,不同包访问,即Son中的Father成员访问get方法是不可见的。而public的话是可见的,所以i访问得到。
private部分是不能继承,属于父类私有,而public的部分,将继承,需要修改的方法,可以进行重写。要添加的属性可以单独添加。
而且继承的方法,如果原本的father的public方法重写之后没将public加上,会有Cannot reduce the visibility of the inherited method from Father,也就是不能减少父类中继承方法的可见性。super指的是父类,即Father。
还有一点是,其实java中所有的类都隐式地继承了Object类。Object是父类,其他类是子类
老外喜欢讲为基类。子类也叫导出类或者派生类。
(3)代理
设计模式里面有个比较难懂的——代理模式,作者讲的很有趣,代理是组合和继承的中庸之道。
package son;
class Father{
public void get(){
System.out.println("father");
}
}
public class Son extends Father{
public static void main(String[] args) {
Father f = new Father();
f.get();
}
}
class FatherProxy{
private Father f = new Father();
public void get(){
f.get();
}
}
像直接把Father当做成员,那么father的方法就暴露给这个类了,那我们可以使用FatherProxy这样的代理类,我自己定义好get方法是怎么拿的,我自己知道是调用father的get方法,但是使用我这个代理的人不知道,我只告诉他你要用就用代理的get的方法就可以了。封装性就体现出来了。上面只是随便敲的一个简单例子。
(4)重写和重载
class Father{
public void get(String s){
System.out.println("father");
}
public void get(boolean b){
System.out.println("boolean");
}
}
public class Son extends Father{
@Override
public void get(String s){
System.out.println("father");
}
// @Override //会有错误提示 因为父类没有该方法,不是重写
public void get(int i ){
System.out.println("sonint");
}
public static void main(String[] args) {
Son s = new Son();
s.get("d");
s.get(false);
s.get(1);
}
}
重写是重新覆盖父类的方法,如果没有重写或者重载,那么子类调用一个子类没有的方法时,其实是调用父类。
重载是同样的方法名,但参数名称不同,为了防止你错误的进行重载可以加上@Override标签,那样会提示你并没有重写方法。
(5)protected
Java编程访问权限的控制代码详解
在前面一篇提前写了,因为之前没讲继承的东西。
可以简单将protected看成父类给儿子继承的遗产,其他非继承类不能访问。
(6)final关键字
加上final关键字的基本类型,表示这个变量初始化后不会改变。类似c的define,你希望一个变量在这个程序里就是这个值不需要改变。就可以用final。
public class Son{
int age = 2;
public static void main(String[] args) {
final int i = 1;
// i = 2; 值不能再改变
final Son son = new Son();
// son = new Son();
//The final local variable son cannot be assigned.
//It must be blank and not using a compound assignment
//final修饰的局部变量son不能被分配,必须为空或者不要再次分配
son.age = 4;
//虽然引用恒定不变,但是,对象本身却可以改变。
}
void change(final int c){
// c= this.age; 无法赋予新值 因为值只有在方法传参决定 对象引用和这个类似
//age ++; 无法改变
}
}
static本来是静态初始化,和final一起用就是占据了一块不能改变的存储空间。
static final即编译期常量,常量名按照c的常量命名传统,全部用大写字母,单词之间用下划线分开。
static final VALUE_ONE = 1;
final修饰方法时
public class Print {
final void cannotprint(){
System.out.println(1);
}
}
public class PrintSon extends Print{
//void cannotprint(){}
//无法重写 因为被final修饰了
public static void main(String[] args) {
PrintSon ps = new PrintSon();
ps.cannotprint();
}
}
可以看成父类要求子类必须继承的不可修改财产(祖传)。private隐式地指定为final,因为private根本就不给你继承。这比给你继承但不能修改还更私有。
顺便将权限理清。
public,公共财产,不止是子类,其他类也可以用。
final,祖传珍宝,留给子类,但不允许修改。
private,父类私有财产,不会给子类继承。
protected,父类专门留给子类的财产,其他人不能用它。
当final修饰的是类的时候,是为了让这个类不会被继承。
(7)继承和初始化
这里的顺序问题是一个很有趣的问题。看例子。
class GrandFather{
private static int i = print();
private static int print(){
System.out.println("g");
return 1;
}
}
class Father extends GrandFather{
private static int i = print();
private static int print(){
System.out.println("f");
return 1;
}
}
public class Son extends Father{
private static int i = print();
private static int print(){
System.out.println("s");
return 1;
}
public static void main(String[] args) {
System.out.println("first");
}
}
打印的结果是first吗?错了。
虽然执行的是main方法,但是看到son这个需要静态初始化的i没有,结果是s,first吗?
这还有初始化的问题,son是继承father,那么编译器会加载father,并初始化i,那father继承grandfather,那么编译器会去加载grandfather,类似递归。
那最后最先初始化的是grandfather的i。
所以最后的结果是:g,f,s,first。
来源:http://blog.csdn.net/iaiti/article/details/38438403


猜你喜欢
- 新手当在一个类文件中进行了一些操作之后,会造成sout快捷命令无法自动生成。比如操作了import引入其它包之后。主要是对IDEA操作的不熟
- 本文实例讲述了C#直线的最小二乘法线性回归运算方法。分享给大家供大家参考。具体如下:1.Point结构在编写C#窗体应用程序时,因为引用了S
- 这篇文章主要介绍了spring cloud Ribbon用法及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学
- 一、返回值格式统一1.返回值介绍在使用controller对外提供服务的时候,很多时候都需要统一返回值格式,例如{"status&
- Spring框架的关键组件是面向方面编程(AOP)框架。面向方面的编程不仅打破程序逻辑分成不同的部分称为所谓的担忧。跨越多个点的应用程序的功
- 如下所示:package com.unionx.wanxue; import java.util.Map; import java.util
- 1.Mybatis的Dao层实现1.1 传统开发方式1.1.1编写UserDao接口public interface UserDao { &
- 问题现象描述:在Activity中控制播放时,按返回键退出应用后,音乐可在后台继续播放。重新进入app,音乐无法停止,重新点击开始播放音乐,
- 环境变量这个概念不陌生, 就是操作系统的环境变量。系统变量就是java本身维护的变量。 通过 System.getProperty 的方式获
- JSON.toJSONString格式化成json字符串时保留null属性使用阿里的com.alibaba.fastjson.JSON格式化
- Viewpager通俗一点讲就是一个允许左右翻转带数据的页面的布局管理器,经常用来连接Fragment,它很方便管理每个页面的生命周期,使用
- 配置文件<?xml version="1.0" encoding="utf-8" ?>&
- 这是 Java 爬虫系列博文的第四篇,在上一篇Java 爬虫数据异步加载如何解决,试试这两种办法! 中,我们从内置浏览器内核和反向解析法两个
- 我们通过一个完整的实例来实现课程信息管理功能的操作,包括查询、修改、删除课程信息的操作。为了简化实例,添加课程信息的操作直接在 SQL Se
- 本文实例为大家分享了Rxjava实现轮询定时器的具体代码,供大家参考,具体内容如下作用1、实现了延迟若干毫秒后,执行next操作,只执行一次
- OkHttp流程图OkHttp基本使用gradle依赖implementation 'com.squareup.okhttp3:ok
- 这篇文章主要介绍了JAVA基于SnakeYAML实现解析与序列化YAML,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 这篇文章主要介绍了如何使用SpEL表达式实现动态分表查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 1. 简单工厂模式简介简单工厂模式(Simple Factory),又被称为"静态工厂方法模式"。它属于"创建
- 近期遇到了DateTime到底是值类型还是引用类型的疑惑,顺势较深入地了解一下DateTime相关的内容结论:DateTime是值类型,因为