几种常见语言的基本语法对比:类,继承,多态。

oc:

基本ok。派生类。通过[super initxxxx] ,  方式来调用基类构造函数。

有2个不完善的地方:

1.当自定义构造函数的时候。没有屏蔽默认构造函数,还需要手工 调用宏定义。

2.派生类,居然可以看到基类的构造函数。这个。。。init 这样的函数也当成了普通的函数。

2个不完美的地方吧。 虽然不完美,但oc还是很便利的语言。莫名好感。

//
//  Goods.h
//  HIWorld
//
//  Created by linson on 2018/9/5.
//  Copyright © 2018年 linson. All rights reserved.
//

#import <Foundation/Foundation.h>

enum enum_goods_type
{
    book,
    fruit
};

@interface Goods : NSObject
@property(nonatomic) int id;
@property(nonatomic) NSString *name;
@property(nonatomic) float price;
@property(nonatomic) enum enum_goods_type gtype;

-(id)init:(int)myid name:(NSString*)name price:(float)price type:(enum enum_goods_type)type;
-(NSString*)MyBaseInfo;
-(NSString*)MyFullInfo;
@end



@interface Books : Goods

-(instancetype) init __attribute__((unavailable("init not available, call sharedInstance instead")));
+(instancetype) new __attribute__((unavailable("new not available, call sharedInstance instead")));


-(id)init:(int)myid name:(NSString *)name price:(float)price type:(enum enum_goods_type)type writer:(NSString *)writer;
@property(nonatomic)NSString *writer;
-(NSString*)MyFullInfo;
@end

@interface Fruit : Goods
-(instancetype) init __attribute__((unavailable("init not available, call init with parameters")));
+(instancetype) new __attribute__((unavailable("new not available, call init with parameters")));

-(id)init:(int)myid name:(NSString*)name price:(float)price type:(enum enum_goods_type)type color:(NSString*)color;
@property(nonatomic)NSString *color    ;
-(NSString*)MyFullInfo;
@end
//
//  Goods.m
//  HIWorld
//
//  Created by linson on 2018/9/5.
//  Copyright © 2018年 linson. All rights reserved.
//

#import "Goods.h"

@implementation Goods

-(id)init:(int)myid name:(NSString*)name price:(float)price type:(enum enum_goods_type)type
{
    if(self=[super init])
    {
        _id=myid;
        _name=name;
        _price=price;
        _gtype=type;
    }
    return self;
}

-(NSString*)MyBaseInfo
{
    NSString *ret=[NSString stringWithFormat:@"id:%i,name:%@,price:%.2f.type:%u",_id,_name,_price,_gtype];
    return ret;
}

-(NSString*)MyFullInfo
{
    return @"";
}

@end


//books
@implementation Books

-(id)init:(int)myid name:(NSString *)name price:(float)price type:(enum enum_goods_type)type writer:(NSString *)writer
{
    self=[super init:myid name:name price:price type:type];
    _writer=[NSString stringWithFormat:@"newinit.%@",writer];
    return self;
}

-(id)initWith_id:(int)myid name:(NSString *)name price:(float)price type:(enum enum_goods_type)type writer:(NSString *)writer
{
    self=[super init:myid name:name price:price type:type];
    _writer=writer;
    return self;
}

-(NSString*)MyFullInfo
{
    //为什么继承后,访问要通过getxxx这个隐藏的方法来访问。
    NSString *ret=[NSString stringWithFormat:@"id:%i,name:%@,price:%.2f.type:%u.writer:%@", self.id,self.name,self.price,self.gtype,_writer];
    return ret;
}

@end


//fruit

@implementation Fruit

-(id)init:(int)myid name:(NSString *)name price:(float)price type:(enum enum_goods_type)type color:(NSString *)color
{
    self=[super init:myid name:name price:price type:type];
    _color=color;
    return self;
}

-(NSString*)MyFullInfo
{
    //为什么继承后,访问要通过getxxx这个隐藏的方法来访问。
    NSString *ret=[NSString stringWithFormat:@"id:%i,name:%@,price:%.2f.type:%u.color:%@", self.id,self.name,self.price,self.gtype,_color];
    return ret;
}

@end

java:

  不存在oc的2个毛病。

1.构造函数是和类同名。所以不存在oc的构造函数问题。

2.自定义构造 函数后。默认的函数,就被屏蔽了。

而且 简洁的 方式,反而 比 在它基础上改良后的c# 更 顺手。

如基类和派生类 没有 任何 关键字。同名就覆盖。怕因为写错方法名字,没覆盖到,就加 @Override.多简洁,多有力。java是默认所有方法都会被覆盖,而c#是默认不会被覆盖,要覆盖先要必须加上virtial关键字。

而 c#.就改良 ,改过 了 。很多地方都改良的很成功。个人不喜欢c#的 继承改良。

java 有时候又有一点不知道 如何说的感觉,如派生类的 构造函数。如果调用基类的构造函数,那么必须写在第一行。否则编译错误。而c#是放在函数定义的那一行上。感觉语法更正规。虽然突兀

在子类的构造函数中第一行有一个默认的隐式语句。 super();

Constructor call must be the first statement in a constructor test.java /javatest/src/com line 39 Java Problem

 
复制代码
//学习了类和继承,以及 派生类的构造以及 方法覆盖。

public static void Study_class() { //goods基类是否应该是一个虚类.其实并不是固定的.看场景,如果把goods基类看作现实物品的基类,那么就应该是虚类.因为不存在一个概念的物品. //但如果把goods 看作是某物品的基本信息类,那么可以是普通类.代表一个物品的基础信息. //下面就是作为基类创建. List<goods> mygoods=new ArrayList<goods>(); goods book_cshart=new goods(0, "c#", 3.1f, enum_goods_type.book); goods book_javaGoods=new goods(1, "java", 4.5f, enum_goods_type.book); goods fruit_apple=new goods(3,"apple",1f,enum_goods_type.fruit); goods fruit_banana=new goods(4,"banana",0.9f,enum_goods_type.fruit); mygoods.add(book_cshart); mygoods.add(book_javaGoods); mygoods.add(fruit_apple); mygoods.add(fruit_banana); for(int i=0;i<mygoods.size();i++) { System.out.println("base:"+mygoods.get(i).MyBaseInfo()); System.out.println("special"+mygoods.get(i).MySpecialInfo()); } //派生类创建 book_cshart=new Book(0, "c#2", 3.1f, "linson", new Date()); book_javaGoods=new Book(10, "java2", 4.5f, "linson", new Date()); fruit_apple=new Fruit(3, "apple2", 1f, "red"); fruit_banana=new Fruit(4,"banana2",0.9f,"yellow"); List<goods> mygoods2=new ArrayList<goods>(); mygoods2.add(book_cshart); mygoods2.add(book_javaGoods); mygoods2.add(fruit_apple); mygoods2.add(fruit_banana); for(int i=0;i<mygoods.size();i++) { System.out.println("base:"+mygoods2.get(i).MyBaseInfo()); System.out.println("special"+mygoods2.get(i).MySpecialInfo()); } }
复制代码

基类:

复制代码
package com.linson;

import java.text.DecimalFormat;

enum enum_goods_type
{
    book,
    fruit;
}


public class goods 
{
    public int id;
    public String name;
    public float price;
    public enum_goods_type gtype;
    
    public goods(int _id,String _name,float _price,enum_goods_type _type)
    {
        id=_id;
        name=_name;
        price=_price;
        gtype=_type;
    }
    
    public String MyBaseInfo()
    {
        DecimalFormat dt=new DecimalFormat();
        dt.applyLocalizedPattern("0.00");
        String priceformat=dt.format(price);
        return "ID:"+id+". Name:"+name+". price:"+priceformat+". type:"+gtype.name();
    }
    
    public String MySpecialInfo()
    {
        return "";
    }
}
复制代码

book 

复制代码
package com.linson;

import java.util.Date;

public class Book extends goods
{
    public String writer;
    public Date publicDate;
    
    public Book(int _id,String _name,float _price,String _writer,Date _publicdate)
    {
        super(_id, _name, _price, enum_goods_type.book);//必须是放在第一行 。
        writer=_writer;
        publicDate=_publicdate;
    }
    
    @Override
    public String MySpecialInfo()
    {
        String retString=MyBaseInfo();
        
        retString=retString+" .Writer:"+writer+".";
        return retString;
    }
}
复制代码

fruit:

复制代码
package com.linson;

public class Fruit extends goods
{
    public String Color;
    
    public Fruit(int _id,String _name,float _price,String _color)
    {
        super(_id, _name, _price,com.linson.enum_goods_type.fruit);
        Color=_color;
    }
    
    @Override
    public String MySpecialInfo()
    {
        String retString=MyBaseInfo();
        
        retString=retString+" .Color:"+Color+".";
        return retString;
    }
}
复制代码

c#. 2 个问题 

1.派生类,构造函数 ,太突兀 。

2. 派生类 的 new 关键字 画蛇添足,反而导致 人心凝聚力下降。记得最初学c#。就是这里搞的人郁闷。虽然搞懂了。但一直想问什么 有这样做。有什么意义。多年后,看其他语言。都没有这个功能。

而且确实没有必要。

学习和思考这种无聊语法,所花费的时间,基本没有任何价值。能不让人郁闷吗。

 

c#.当然好的地方。还是细微的上的好处。  float格式化,方便。 枚举,直接 v.tosting。方便,人性。

唉,改良,完善,是把双刃剑。好了,很好。过了,就。。。没法吧。

希望c#,删掉 改良改过的语法。精简点更好。可以加语法糖。别多加 没有实质提升的,实现功能的道路。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//1.派生类的写法.是否会屏蔽默认的构造函数.

namespace helloworld
{
    public enum goods_type
    {
        book,
        fruit
    };

    public class Goods
    {
        public int id;
        public string name;
        public float price;
        public goods_type type;

        public Goods(int _id, string _name, float _price, goods_type _type)
        {
            id = _id;
            name = _name;
            price = _price;
            type = _type;
        }

        public string MyBaseInfo()
        {
            return "ID:" + id + ". Name:" + name + ". price:" + price.ToString(".00") + ". type:" + type.ToString();
        }

        public virtual string MyFullInfo()//virtual 和 override 最好配对,个人感觉只需要override  关键字,不需要new 关键字.
        {
            return "noway";
        }

    }


    public class Books:Goods
    {
        public string writer;

        //这里构造函数的语法,像c++,是放在函数定义的同一行 。而java是放入在函数块的第一行。不再第一行会报错。如果是这样的话。还是挺c#.感觉更符合语意。
//虽然之前很讨厌这种写法
public Books(int _id, string _name, float _price, goods_type _type,string _writer):base(_id,_name,_price,_type) { writer = _writer; } public override string MyFullInfo() { return "ID:" + id + ". Name:" + name + ". price:" + price.ToString(".00") + ". type:" + type.ToString() + ".wirter:" + writer; } } public class Fruit : Goods { public string color; public Fruit(int _id, string _name, float _price, goods_type _type, string _color) : base(_id, _name, _price, _type) { color = _color; } public override string MyFullInfo() { return "ID:" + id + ". Name:" + name + ". price:" + price.ToString(".00") + ". type:" + type.ToString() + ".color:" + color; } } }
原文地址:https://www.cnblogs.com/lsfv/p/9596720.html