- java中匿名类的实现要么是实现接口的类要么是父类的一个子类,C#中没有这个限制
- java中引用类型之间的转换都是显示类型转换,且具有继承或实现接口的条件,C#中还可以通过关键字explicit和implicit关键字声明
- 继承和实现接口的区别
- try-catch
- 输出方式不同
- 迭代器和增强for遍历
- 常量的声明不同
引用类型转换
java
package test;
/*
* 测试多态的使用
*/
public class Test2 {
public static void main(String[] args) {
//1.子类转换成父类
//1.1只可以使用父类的中的方法
Animal a1 = (Monkey)new Monkey();//此时Monkey可以省略,即显式隐式转换都可以
a1.name();
//2. 实现类转换成接口
//2.1 对象可以使用的是实现类的方法
Creature c1 = (Monkey)new Monkey();//此时Monkey可以省略,即显式隐式转换都可以
c1.grow();
}
}
class Stone{
int age;
public void age() {
System.out.println("石头有年龄");
}
}
//1.接口不能有成员变量,除非是static final
//2.接口中的所有方法必须是抽象方法
//3.接口只能继承接口
interface Creature{
public void grow();
}
class Animal {
String name;
public void name() {
System.out.println("动物有名字");
}
}
//1. 子类只能继承一个父类,但可以实现多个接口
//2. 类实现接口时必须重写接口中的所有抽象方法,否则该类要声明为抽象类
class Monkey extends Animal implements Creature{
int age;
public void eat() {
System.out.println("猴子爱吃香蕉");
}
@Override
public void grow() {
System.out.println("小猴子长成大猴子");
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace study_2
{
class MyStudy
{
static void Main(string[] args)
{
//1. 子类转换成父类,同java
Animal a1 = (Monkey)new Monkey();//此时Monkey可以省略,即显式隐式转换都可以
a1.Name();
//2. 接口测试:待定
//3.显示:explicit 隐式:implicit
Stone s1 = new Stone();
s1.age = 3000;
Monkey monkey = (Monkey)s1;
Console.WriteLine(monkey.age);
//4. 隐式
Tree tree = new Tree();
tree.energy = 1000;
Monkey monkey2 = tree;
Console.WriteLine(monkey2.energy);
}
}
class Stone
{
public int age;//默认类型外部不可访问
public void Age()
{
Console.WriteLine("石头有年龄");
}
}
class Tree
{
public double energy;
public void magic()
{
Console.WriteLine("树的魔法");
}
}
class Animal
{
public String name;
public void Name()
{
Console.WriteLine("动物有名字");
}
}
class Monkey:Animal
{
public int age;
public double energy;
public void Eat()
{
Console.WriteLine("猴子爱吃香蕉");
}
//1. 显示转换成Stone类
public static explicit operator Monkey(Stone stone)
{
Monkey monkey = new Monkey();
monkey.age = stone.age/500;
return monkey;
}
//2. 隐式转换成Tree类
public static implicit operator Monkey(Tree tree)
{
Monkey monkey = new Monkey();
monkey.energy = tree.energy/2;
return monkey;
}
}
}
匿名类及匿名对象的比较
java
package test;
public class Test3 {
public static void main(String[] args) {
//1. 匿名对象
new Animal().name();
//2.匿名子类
//2.1 仅仅创建一个匿名子类
new Animal() {
}.name();
//2.2. 对匿名子类的内容修改;只能是方法的重写,如果有成员变量,只能内部调用,外部无法调用
Animal a1 = new Animal(){
public int number = 1;
@Override
public void name() {
System.out.println("我是Animal类的一个匿名子类:"+number);
}
};
a1.name();
//System.out.println(a1.number);//错误
//3.匿名实现类
new Creature() {
@Override
public void grow() {
System.out.println("我是接口的匿名实现类,重写了grow方法");
}
}.grow();
}
}
C#
匿名类中的成员限制强
//匿名类的对象
var anny = new
{
name = "匿名",
age = 25
};
Console.WriteLine(anny.name);
try-catch
-
try-catch中吧变量的定义声明在try前面的原因就是让try外面的语句也能使用该变量,如果声明在try内部,则try外面的语句无法获取该变量
-
C#中catch后面可以为空什么都不写,java不行,C#中catch如果捕获异常,可以不写异常变量,java不行
-
示例:略
继承和实现接口
- java中使用extends表示继承,implements表示实现接口
- C#中用 :把继承和接口都表示了。
迭代器和增强for遍历
java
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
* 测试java迭代器
*/
public class Test4 {
public static void main(String[] args) {
// 1. 数组
int[] arr = { 1, 2, 3, 4, 5 };
// 2. 集合
List<Integer> myList = new ArrayList<Integer>();
for (int i = 0; i < 5; i++) {
myList.add(i);
}
// 1. 获取迭代器
Iterator<Integer> it = myList.iterator();
// 使用迭代器遍历
System.out.println("迭代器遍历:");
while (it.hasNext()) {
System.out.println(it.next());
}
//2. 使用增强for遍历
System.out.println("增强for遍历:");
for(int item:myList) {
System.out.println(item);
}
// HashMap迭代器遍历
Map<String, Integer> myMap = new HashMap<String, Integer>();
for (int i = 0; i < 5; i++) {
myMap.put("" + i, i);
}
Iterator it2 = myMap.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry<String, Integer> entries = (Map.Entry) it2.next();
// System.out.print(entries.getKey());
// System.out.print(entries.getValue());
System.out.println(entries);
}
}
}
C#
//迭代器:数组和集合都可以使用
Console.WriteLine("迭代器遍历:");
int[] arr = { 1, 2, 3, 4, 5 };
IEnumerator enumerator = arr.GetEnumerator();
while(enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
//foreach遍历:数组和集合都可以使用
Console.WriteLine("foreach遍历:");
foreach(int n in arr)
{
Console.WriteLine(n);
}
常量的声明
- C#Const成员常量可以让类直接使用(不加static也可以)
- java中final成员常量如果要让类直接使用,必须加static
C#
(1) readonly和const都是用来标示常量的。
(2) 初始化赋值不同。
const修饰的常量必须在声明的同时赋值。例如:
public class Class1
{
public const int MaxValue = 10; //正确声明
public const MInValue; //错误:常量字段要求提供一个值
public Class1()
{
MinValue = 10;
}
}
- readonly字段可以在初始化(声明或构造函数)的过程中赋值。因此,根据所使用的构造函数,readonly字段可能具有不同的值。
public class Class1
{
public readonly int c = 10; //正确声明
public readonly int z;
public Class1()
{
z = 24;//正确
}
protected void Load()
{
z = 24;//错误:无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
}
}
- const修饰的值的类型也有限制,它只能为下列类型之一(或能够转换为下列类型):sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string、enum类型或引用类型。注意能够声明为const的引用类型只能为string或值为null的其他引用类型。readonly可以是任何类型。