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; } } }