Go语⾔和Java的⾯向对象⽐较
⽤写论⽂的⼼态写博客
中国的百度百科上对Go语⾔是这样阐述的:“Go(⼜称Golang)是Google开发的⼀种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语⾔”。上对Go语⾔是这样阐述的:“Go (also referred to as Golang) is a statically typed, compiled programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson.Go is syntactically similar to C, but with memory safety, garbage collection, structural typing,and CSP-style concurrency.”。上翻译过来意思其实和百度百科差不多。不管是百度还是维基都没有直接说Go语⾔到底是不是⼀门⾯向对象的语⾔。
这⼀来,就导致了业内对Go语⾔到底是不是⼀门⾯向对象的语⾔产⽣了⼀波讨论。有的认为Go语⾔没有像Java⼀样通过Class关键字直接标记类,所以严格意义上来说Go语⾔不是⼀门⾯向对象的编程语⾔。有的认为Go语⾔虽然没有直接使⽤像Java和C#的Class关键字,但是Go语⾔可以通过⼀些编程技巧,⽐如巧妙的使⽤结构体,接⼝等,Go语⾔同样能达到与⾯向对象同样效果,所以这⼈认为Go语⾔是⼀门⾯向对象的编程语⾔。“公说公有理,婆说婆有理”,笔者⽐较偏向后者的观点。
业内基本上说⾯向对象都是说Java,C#等⾼级编程语⾔。通过其他语⾔总结出了⾯向对象的三⼤特性:封装、继承和多态。以下是摘⾃博客园博主的三段⽂字介绍。
封装,就是把客观事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让可信的类或者对象操作,对不可信的进⾏信息隐藏。⼀个类就是⼀个封装了数据以及操作这些数据的代码的逻辑实体。在⼀个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种⽅式,对象对内部数据提供了不同级别的保护,以防⽌程序中⽆关的部分意外的改变或错误的使⽤了对象的私有部分。
不知道读者是否学过Java代码,在Java中,我们会经常看到如下代码:⼀个矩形的简单定义,x代表的是长,y代表的是宽。Rect⽅法是⼀个构造函数,getArea⽅法是⼀个求该矩形⾯积函数。private和public代表属性或者⽅法的访问权限。在Java中,通过关键字private、public、protected、default来控制访问权限,⽽在Go语⾔中则是通过申明变量的⼤⼩写字母来控制变量和⽅法的访问权限,字母开头以⼤写则为包外可见,开头以⼩写则为包内可见。
public class Rect {
private int x;//矩形的长
private int y;//矩形的宽
public Rect(int x, int y) {//构造函数
this.x = x;
this.y = y;
}
public int getX() {//getter
return x;
}
public void setX(int x) {//setter
this.x = x;
}
public int getY() {//getter
return y;
}
public void setY(int y) {//setter
this.y = y;
}
public int getArea(){//求⾯积函数
return x * y;
}
}
⽽在Go语⾔中,上⾯的Java代码,则要写成如下。
type Rect struct {
x,y int
}
func (r *Rect) GetArea() int{
return r.x * r.y
}
func NewRect(x, y int) *Rect {
return &Rect{x,y}
}
func (r *Rect) SetX(x int) {
r.x=x
}
func (r *Rect) GetX() int {
return r.x
java技术介绍百度百科
}
func (r *Rect) SetY(y int) {
r.y = y
}
func (r *Rect) GetY() int {
return r.y
}
对于初学者⽽⾔,可能不太明⽩为什么func后要加(r *Rect),这是因为Go语⾔⽐较酷炫的地⽅。我们把这个叫做“为特定类型定义函数”,也就是说为该类型的对象定义⽅法。要是⼤家想了解更多Go中关于函数的知识点,可以参考。作者写得⼗分的详细。
继承,指可以让某个类型的对象获得另⼀个类型的对象的属性的⽅法。它⽀持按级分类的概念。继承是指这样⼀种能⼒:它可以使⽤现有类的所有功能,并在⽆需重新编写原来的类的情况下对这些功能
进⾏扩展。 通过继承创建的新类称为“⼦类”或“派⽣类”,被继承的类称为“基类”、“⽗类”或“超类”。继承的过程,就是从⼀般到特殊的过程。要实现继承,可以通过 “继承”(Inheritance)
和“组合”(Composition)来实现。继承概念的实现⽅式有⼆类:实现继承与接⼝继承。实现继承是指直接使⽤基类的属性和⽅法⽽⽆需额外编码的能⼒;接⼝继承是指仅使⽤属性和⽅法的名称、但是⼦类必须提供实现的能⼒。
Java中继承是⽐较常⽤的。为了给⼤家更好的⽐较Java与Go中对继承的设计。我们直接上代码,参考。
public class Address {
public int number;
public String Street;
public String City;
public String State;
public String Country;
}
public class Person extends Address{
private String name;
public void Talk(){
System.out.println("Hi!My name is "+name);
}
public void Location(){
System.out.println("I am at "+number+","+Street+","+City+","+State+","+Country);
}
}
那么在Go语⾔中,上⾯的代码要写成这个样⼦。通过下⾯例⼦,我们可以看到其实Go语⾔的设计者在
设计过程中,并没有特意去强调继承这⼀概念,⽽是通过使⽤结构体⾥申明其他结构体的⽅式来巧妙的避开了继承这个问题。
type Address struct {
Number int
Street string
City string
State string
Country string
}
type Person struct {
Name string
adrs Address
}
func (p *Person) Talk() {
fmt.Println("Hi!My name is ",p.Name);
}
func (p *Person) Location() {
fmt.Println("I am at "+strconv.Itoa(p.adrs.Number)+","+p.adrs.Street+","+p.adrs.City+","+p.adrs.State+","+p.adrs.Country);
}
多态,是指⼀个类实例的相同⽅法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接⼝。这意味着,虽然针对不同对象的具体操作不同,但通过⼀个公共的类,它们(那些操作)可以通过相同的⽅式予以调⽤。
Java中的多态其实并不难理解,说得简单点就是“向上转型”和“向下转型”。Java多态存在的前提是1)要有继承2)要有重写3)⽗类引⽤指向⼦类对象。我们再来看⼀段Java代码多态的例⼦。
public class Main {
public static void main(String[] args) {
Person boy = new Boy("Li Hua");
Person girl = new Girl("Xiao Hong");
List<Person> list = new ArrayList();
list.add(boy);
list.add(girl);
for (int i=0;i<list.size();i++) {
Person person = (i);
person.SayHello();
}
}
}
public class Person{
public void SayHello(){
}
}
public class Boy extends Person {
public String name;
public Boy(String name) {
this.name = name;
}
@Override
public void SayHello() {
super.SayHello();
System.out.println("My name is " + name);
}
}
public class Girl extends Person {
public String name;
public Girl(String name) {
this.name = name;
}
@Override
public void SayHello() {
super.SayHello();
System.out.println("My name is " + name);
}
}
那假如⽤Go语⾔⼜如何实现类似于Java中的多态呢?我们将上⾯的代码改成⽤Go来实现。注意同样在定义Person的时候,Java使⽤的是Class,⽽Go使⽤的Interface。
type Person interface {
SayHello()
}
type Boy struct {
Name string
}
type Girl struct {
Name string
}
func (this *Boy) SayHello() {
fmt.Println("My name is ", this.Name)
}
func (this *Girl) SayHello() {
fmt.Println("My name is ", this.Name)
}
func main() {
g := &Girl{"girl"}
b := &Boy{"boy"}
p := map[int]Person{}
p[0] = g
p[1] = b
for _, v := range p {
v.SayHello()
}
}
其实从上⾯的多态的例⼦,我们不难发现Go在对多态的代码风格上要⽐Java更加的简洁。好了,这就是关于Go与Java对⾯向对象的⼀些粗略解释。笔者资历尚浅,欢迎批评指正。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论