目录
- 我的学习过程
- 我的心路历程
- 思考总结
我的学习过程
昨天学习qiujuer老师的《Socket网络编程进阶与实战》实战课程中,写了一个简易的client-server聊天项目。我的学习方法是根据课程的一部分思路提示后,自己独自进行编写,出现了很多问题,今天尝试着从源码找原因,学习了不少知识。
我的心路历程
我是用到socket来写client-server信息传输功能,socket包主要用到三个方法:
- connect(SocketAddress):viod
- getInputStream():InputStream
- getOutputStream():OutputStream
在使用connect方法时,我尝试new一个SocketAddress对象作为connect的参数。结果报错说:
SocketAddress是抽象的,不能被实例化。
我的操作心路:
我使用command+click进入查看了SocketAddress,发现它是一个抽象类,是一个不可变对象。源码指示@see Socket包参考,思维中断。什么意思呢?为什么要传一个抽象对象作为参数,却又无法实例化?
我的操作心路:
对比了课程中的写法,发现课程使用的是InetSocketAddress。使用command+click进入,定位到了构造器:
//Java代码
public InetSocketAddress(InetAddress addr, int port) {holder = new InetSocketAddressHolder(null,addr == null ? InetAddress.anyLocalAddress() : addr,checkPort(port));}
我一开始以为这是一个methed,怎么可以new一个methed作为参数呢?
我的操作心路:
我选中InetSocketAddress,用command+fn+F12调出所有method,显示InetSocketAddress(InetAddress, int)前有个小m,这应该也是方法,好奇怪?
我的操作心路:
我把源码往上拉,发现InetSocketAddress(InetAddress, int)确实是InetSocketAddress的构造器。真是有点学晕了,哈哈哈。那为什么传InetSocketAddress对象呢?
我的操作心路:
我百度了一下SocketAddress类和InetSocketAddress类。我发现,SocketAddress是抽象类,InetSocketAddress是前者的唯一子类。是唯一子类吗?
我的操作心路:
我选中SocketAddress,使用control+H查看了SocketAddress的所有子类,确实只有一个子类InetSocketAddress。进一步通过百度知道,可以使用SocketAddress的默认构造器来使用子类来建立InetSocketAddress对象作为参数。原来突破点在借助默认构造器和非抽象子类。
思考总结
SocketAddress是一个抽象类,它无法实例化。它只有一个子类InetSocketAddress。当一个抽象类需要“实例化”时,若它具备非抽象的子类,则可以通过抽象类的默认构造器来建立一个实例化的子类对象,实现“实例化”。