/**
* 一个泛化的Shape 由个别到普通的过程
*/
abstract class Shape{
void draw(){System.out.println(this + ".draw()");}
abstract public String toString();
}
/**
* 个别特殊的类型
*/
class Circle extends Shape{
//toString()方法
public String toString() {return "Circle";}
}
class Square extends Shape {
public String toString() {return "Square";}
}
class Triangle extends Shape{
public String toString() {return "Triangle";}
}
public class Shapes {
public static void main(String[] args) {
//在List中放入一个泛化的Shape类型,
List shapeList = Arrays.asList(
new Circle(),new Square(), new Triangle());
for(Shape shape : shapeList)
/**
* 因为泛化的Shape动态绑定了draw()方法,其子类型也会覆盖此方法,也可以产生正确的行为。
* 多态,运行时识别对象的类型,调用相应方法
*/
shape.draw();
}
}
/**
Circle.draw()
Square.draw()
Triangle.draw()
*/
通常,你希望大部分代码尽可能少的了解对象的具体类型,而只与一个泛化类型表示。这样的代码更容易写,读,切更便于维护;设计也更容易实现、理解和改变。
所以“多态”是面向对象的基本目标。
class Candy{
static {System.out.println("Loading Candy");}
}
class Gum{
static {System.out.println("Loading Gum");}
}
class Cookie{
static {System.out.println("Loading Cookie");}
}
public class SweetShop {
public static void main(String[] args) {
System.out.println("inside main");
new Candy();//如果没有.class文件,会自动生成一个同名的.class文件。
System.out.println("After creating Candy");
try{
/**
* Class对象和其他对象一样,我们可以获取并操作它的引用(类加载器)
* Class的静态成员,得到这个名字的类,返回一个Class对象的引用
*
* Class.forName("Gum")方法如果找不到要加载的类(.class文件)就会抛出异常
*/
Class.forName("Gum");
}catch (ClassNotFoundException e) {
//找不到类Gum,因为它还没有被第一次加载过(也就是说这个类的静态成员一次也没有引用过)
System.out.println("Couldn't find Gum");
}
}
}
interface HasBatteries{}
interface Waterproof{}
interface Shoots{}
class Toy{
Toy() {}
Toy(int i){}
}
class FancyToy extends Toy implements
HasBatteries , Waterproof, Shoots{
FancyToy() {super(1);}
}
public class ToyTest {
static void printInfo(Class cc){
System.out.println("类名: " + cc.getName()
+ " 是否接口? [" + cc.isInterface() + "]");
System.out.println("简单类名: " + cc.getSimpleName());
System.out.println("规范名: " + cc.getCanonicalName());
System.out.println();
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("com.yue.rtti.FancyToy");//获取一个Class对象
} catch (ClassNotFoundException e) {
System.out.println("Can't find FancyToy");
System.exit(1);
}
printInfo(c);//第一次输出信息
//getInterfaces会返回此Class对象所表示的类实现的所有接口 是数组形式 Class[]
System.out.println("以下是此类的全部接口");
for(Class face : c.getInterfaces())
printInfo(face);//逐条打印
System.out.println("以上是此类的全部的接口");
Class up = c.getSuperclass();//获取到此类的超类 即父类 基类
Object obj = null;
try {
obj = up.newInstance();//使用这个类的Class对象创建一个具体的对象,并赋予一个obj引用
} catch (InstantiationException e) {
System.out.println("Cannot instantite");
System.exit(1);
} catch (IllegalAccessException e) {
System.out.println("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());//打印
}
}
/**
类名: com.yue.rtti.FancyToy 是否接口? [false]
简单类名: FancyToy
规范名: com.yue.rtti.FancyToy
以下是此类的全部接口
类名: com.yue.rtti.HasBatteries 是否接口? [true]
简单类名: HasBatteries
规范名: com.yue.rtti.HasBatteries
类名: com.yue.rtti.Waterproof 是否接口? [true]
简单类名: Waterproof
规范名: com.yue.rtti.Waterproof
类名: com.yue.rtti.Shoots 是否接口? [true]
简单类名: Shoots
规范名: com.yue.rtti.Shoots
以上是此类的全部的接口
类名: com.yue.rtti.Toy 是否接口? [false]
简单类名: Toy
规范名: com.yue.rtti.Toy
*/
class Initable{
static final int saticFinal = 47;
static final int staticFinal2 = //注意这种情况也会被初始化的,虽然是final,但具有不确定性,非常数静态域。
ClassInitialization.rand.nextInt(1000);
static {
System.out.println("Initializing Initable");
}
}
class Initable2{
static int staticNonFinal = 147;//非常数静态域
static{
System.out.println("Initializing Initable2");
}
}
class Initable3{
static int staticNonFinal = 74;
static {
System.out.println("Initializing Initable3");
}
}
//有继承超类的情况,情况不特殊也不会被初始化
class Initable4 extends Initable3{
static final int saticFinal = 123;
static {
System.out.println("Initializing Initable4");
}
}
public class ClassInitialization {
public static Random rand = new Random(47);
public static void main(String[] args) throws ClassNotFoundException {
//得到一个Class对象 这样不会先对其初始化,而是把初始化延迟到了第一次使用其静态域时。
Class initable = Initable.class;
System.out.println("After creating Initable ref");
System.out.println(Initable.saticFinal);
//仅仅是编译器常量还不足以保证不初始化
System.out.println(Initable.staticFinal2);
//直接使用一个类的静态域(他不是final的) 其他静态域也会被初始化
System.out.println(Initable2.staticNonFinal);
//另一种方式获取Class对象 这样会首先对其初始化
Class initable3 = Class.forName("com.yue.rtti.Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
System.out.println("继承超类的情况:"+Initable4.saticFinal);
}
}
/**
After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74
继承超类的情况:123
*/
public class GenericClassReferences {
public static void main(String[] args) {
Class intClass = int.class;//普通的Class引用
Class genericIntClass = int.class;//使用泛型限定的Class引用,只能指向指定的引用的Class对象
// genericIntClass = double.class;//这里会报错,因为使用了泛型进行限定
//普通的类引用不会产生警告信息,可以指向任何其他Class对象
intClass = double.class;
//使用通配符来指定此泛型的限定范围
Class extends Number> genericNumberClass = int.class;
}
}
Class> intClass = int.class;
Class>优于平凡的Class,即便他们是等价的,Class>表示使用了一个非具体的类引用,就选择了非具体的版本。//使用通配符来指定此泛型的限定范围
Class extends Number> genericNumberClass = int.class;
class CountedInteger {
private static long counter;
private final long id = counter++;
public String toString() {return Long.toString(id);}
}
public class FilledList {
public static void main(String[] args) {
// CountedInteger类必须有一个无参构造器
Class type = CountedInteger.class;
try {
//这个类必须假设与它一同工作的任何类型都有一个某人的构造器(无参构造器),否则抛出异常
CountedInteger obj = type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
当你将泛型语法用于Class对象时,newInstance()将返回改对象的确切类型,而不仅仅是基本的object(普通的Class引用)//class Toy{
// Toy() {}
// Toy(int i){}
//}
//class FancyToy extends Toy implements
//HasBatteries , Waterproof, Shoots{
// FancyToy() {super(1);}
//}
public class GenericToyTest {
public static void main(String[] args) throws Exception {
Class ftClass = FancyToy.class;
FancyToy fancyToy = ftClass.newInstance();
// Class up2 = ftClass.getSuperclass();//这样编译器会报错
//?代表某个类 他是FancyToy的超类,而不会接受Class up2这样的声明
Class super FancyToy> up = ftClass.getSuperclass();
Object obj = up.newInstance();
}
}
class Building {}
class House extends Building {}
public class ClassCasts {
public static void main(String[] args) {
Building b = new House();
Class houseType = House.class;//先获得目标转型的Class引用
House h = houseType.cast(b);//使用cast进行转型的语法
h = (House) b;//直接转型的语法
}
}
if (h instanceof Building) {
h = (House) b;
}
class Building {}
class House extends Building {}
public class ClassCasts {
public static void main(String[] args) {
Building b = new House();//这里引用的实际对象是一个House,它在运行时会识别这个类型RTTI
Class houseType = House.class;
Class buildType = Building.class;
House h = houseType.cast(b);//使用cast进行转型的语法
h = (House) b;//直接转型的语法
if (h instanceof Building) {
h = (House) b;
System.out.println("转型");
}
if (buildType.isInstance(b)) {//可以改写成这样
System.out.println(buildType.isInstance(b));
}
}
}
+++这是一种方法,根据不同情况会有不同的实现。
这个东西会在设计模式中说。
class Base{}
class Derived extends Base{}
public class FamilyVsExactType {
static void test(Object x){
System.out.println("测试x的类型 " + x.getClass());
System.out.println("x instanceof Base: " + (x instanceof Base));
System.out.println("x instanceof Derived: " + (x instanceof Derived));
System.out.println("Base.isInstance(x): " + Base.class.isInstance(x));
System.out.println("Derived.isInstance(x): " + Derived.class.isInstance(x));
System.out.println("下面的输出与上面对比");
System.out.println("x.getClass() == Base.class: " + (x.getClass() == Base.class));
System.out.println("x.getClass() == Derived.class: " +(x.getClass() == Derived.class));
System.out.println("x.getClass().equals(Base.class): " + (x.getClass().equals(Base.class)));
System.out.println("x.getClass().equals(Derived.class): " + (x.getClass().equals(Derived.class)));
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++");
}
public static void main(String[] args) {
test(new Base());
test(new Derived());
}
}
/**
测试x的类型 class com.yue.rtti.Base
x instanceof Base: true
x instanceof Derived: false
Base.isInstance(x): true
Derived.isInstance(x): false
下面的输出与上面对比
x.getClass() == Base.class: true
x.getClass() == Derived.class: false
x.getClass().equals(Base.class): true
x.getClass().equals(Derived.class): false
++++++++++++++++++++++++++++++++++++++++++++++
测试x的类型 class com.yue.rtti.Derived
x instanceof Base: true
x instanceof Derived: true
Base.isInstance(x): true
Derived.isInstance(x): true
下面的输出与上面对比
x.getClass() == Base.class: false
x.getClass() == Derived.class: true
x.getClass().equals(Base.class): false
x.getClass().equals(Derived.class): true
++++++++++++++++++++++++++++++++++++++++++++++
*/