java面向对象(1)

1、extends和final

    java的类中没有多重继承,只有多层继承。java中所有的类都是从java.lang.Object直接或间接派生,所以类都具有其方法。使用extends来从指定类继承,如果不想类当做父类即不能派生其它类,可以使用final来声明这个类(String、System都是final类型):

class Base{}
final class sub extends Base{}

2、override

    java中子类重写(覆盖)父类方法时,子类方法的返回值类型应该与父类方法相等或更小,子类方法抛出的异常类也是应与父类方法相等或更小。使用super来调用父类中被覆盖的方法,跟this一样,super也不能出现在静态方法中,因为它是通过一个对象而不是类来调用的:

class Base
{
	public int num;
	public void func()
	{
		System.out.println("Base func");
	}
}
class Sub extends Base
{
	public int num = 10;
	public void func()
	{
		System.out.println("Sub func");
	}
	public void test()
	{
		int i = num; //使用子类的num
		int j = super.num; //使用父类的num
		
		
		func(); //调用子类的func
		super.func(); //调用父类的func
	}
}

    子类重写父类的成员变量时,相当于隐藏了父类中的成员变量:

class Parent
{
	public String tag = "Parent";
}

class Child extends Parent
{
	private String tag = "Child";
}

public class Test
{
	public static void main(String[] args)
	{
		Child d = new Child();
		//String s = d.tag; //错误,父类中tag被隐藏
		String str = ((Parent)d).tag; //强制转换后可以访问tag
	}
}

3、初始化块

    使用{}来定义初始化块,初始化块在构造函数之前执行,初始化块与成员变量初始化的执行先后顺序为代码的先后顺序,且如果初始化块在成员变量初始化之前的话,初始化块内只能对该成员变量进行初始化,不能引用该成员变量。static{}用来定义静态初始化,其类似于静态成员函数,不属于某个对象而属于整个类,所以其执行顺在普通初始化块之前:

public class Test
{
	{
		//第二执行
		num = 10;
		//System.out.println(num); //错误,不可以引用num
	}
	public int num = 20; //第三执行
	{
		//第四执行
		num = 30;
		System.out.println(num); //可以引用num
	}
	public Test()
	{
		//最后执行
		System.out.println("Test");
	}
	static
	{
		//最先执行
		System.out.println("dd");
	}
	public static void main(String[] args)
	{
		Test t = new Test();
	}
}

4、构造函数

    java类中也存在一个不带任何参数的默认构造函数,当自定义了构造函数后就不再调用它。类的对象在内存分配后会自动进行成员变量的初始化,初始化规则与数组自动初始化规则相同,即数值类元素初始化为0、boolean类型为false、引用类型为null。子类中通过super来调用父类的构造函数,完成父类的初始化:

class Parent
{
	public String name;
	public double size;
	public Parent(String name, double size)
	{
		this.name = name;
		this.size = size;
	}
}

class Child extends Parent
{
	public String color;
	public Child(String name, double size, String color)
	{
		super(name, size);
		this.color = color;
	}
	public static void main(String[] args)
	{
		Child c = new Child("测试", 5.6, "红色");
	}
}

    java中构造函数可以调用另一个构造函数,通过this:

public class Apple
{
	public String name;
	public String color;
	public double weight;
	public Apple(String name, String color)
	{
		this.name = name;
		this.color = color;
	}
	public Apple(String name, String color, double weight)
	{
		this(name, color);
		this.weight = weight;
	}
}

5、父类子类的转换

    子类对象可以赋值给父类引用变量;父类对象不能赋值给子类引用变量;父类引用可以强制转换为子类引用,此时父类引用必须实际指向的是一个子类对象,如:

		Object obj = "test"; //子类String对象赋值给父类Object引用变量
		String s = new Object(); //子类引用不能指向父类对象
		String str = (String)obj; //可以将obj强转为String对象,因为对象obj实际上是一个String类型

    在强制转换之前可以使用instanceof运算符来判断这个对象是否是指定类型或其子类或其实现类:

		Object obj = "test"; 
		if(obj instanceof String)
		{
			String str = (String)obj;	
			System.out.println("df");
		}

6、多态

class Base
{
	public int id = 0;
	public void func()
	{
		System.out.println("Base func");
	}
}

class Sub extends Base
{
	public int id = 1;
	public void func()
	{
		System.out.println("Sub func");
	}
	public void test(){}
	public static void main(String[] args)
	{		
		Base b; //b编译时类型为父类Base
		b = new Sub(); //允许将子类对象赋给父类引用变量
		b.func(); //输出为"Sub func",即b运行时类型为子类Sub,是多态的表现
		int i = b.id; //i为0,成员变量不具备多态性
		
		//b.test(); //错误,不能调用非重写函数
		((Sub)b).test(); //强制类型转换后可以调用非重写函数,Base父类对象b实际上是一个Sub子类对象,所以可以强制类型转换
	}
}

猜你喜欢

转载自blog.csdn.net/milanleon/article/details/80324946