Java_面向对象(1)_续

代码整理:(马士兵)

/*范例名称:
 * 原文件名称:
 * 要点:
 * 1. 面向对象
 * 2.关键字:
 * 		this--在类的方法中使用this表示使用该方法的对象的引用;
 * 		super--当前对象父类的引用;可以认为子类对象中默认调用了super()方法来实例化一个父类对象;
 * 		static--在类中声明变量时,为类的公用变量,在第一次使用时被初始化,仅此一份;
 * 				声明方法时,调用该方法时不会将对象的引用传递给他,不可访问非static成员;
 * 				非静态成员专属于某一个对象, 即必须通过实例化对象引用;
 * 				可以通过对象引用或者类名(不需要实例化)访问静态成员
 * 		package/import--打包/引入包
 * 		Java只支持单继承(C++可以多继承)
 * 修饰对象成员的访问权限 
 * 		private--类内部
 * 		default--类内部、同一个包
 *		protected--类内部、同一个包、子类
 * 		public--类内部、同一个包、子类、任何地方
 * 		(class的权限休书只可以用public跟default)
 * 
 * 		instanceof--判断该引用型“指向”对象是否属于该类或者该类的子类
 * 
 * 		abstract--抽象类/抽象方法; 相当于c++里边的virtual; 抽象类是用来被继承的(不能被实例化); 抽象方法只需要声明, 子类中需要重写相应的方法
 * 		final--变量不能被修改, 方法不能被重写, 类不能被继承; 相当于c++里边的const
 * 		inerface--接口, 是一种特殊的抽象类, 只包含常量和方法定义; 通过实现多接口实现"类多继承"
 */
public class ObjectTest {
	private static int sid = 0;
	private String name;
	int id;

	ObjectTest(String name) {
		this.name = name;
		id = sid++;
	}

	public void info() {
		System.out.println("My object's name is " + name + " No. " + id);
	}

	public static void main(String[] args) {
		// 测试一
		System.out.println("***************");
		System.out.println("测试一");
		System.out.println("***************");
		ObjectTest.sid = 100;
		ObjectTest mimi = new ObjectTest("Mimi");
		mimi.sid = 200;
		ObjectTest papa = new ObjectTest("Papa");
		mimi.info();
		papa.info();

		// 测试2
		System.out.println("***************");
		System.out.println("测试二:继承、重写、访问权限");
		System.out.println("***************");
		Student student = new Student();
		student.setName("Jhon");
		student.setAge(12);
		student.setSchool("Stanford");
		System.out.println("重写toString的结果: " + student);// 此处student相当于student.toString()
		Student student2 = new Student();
		student2.setName("Jhon");
		student2.setAge(12);
		student2.setSchool("Stanford");
		System.out.println("student==student2? " + student.equals(student2));

		// 测试3
		System.out.println("***************");
		System.out.println("测试三:动态绑定和多态");
		System.out.println("***************");
		Teacher teacher1 = new Teacher();
		student.yingDa();
		teacher1.yingDa();
		Lady l1=new Lady("l1", teacher1);//这里比较有意思,体现 动态绑定
		l1.ladyYingDa();//此处方法里边调用的yingDa()方法由运行时new的对象(Teacher)决定
		//其实原理是因为,实例化子类对象时,其(包含)生成的父类对象的方法的指针由于子类重写的缘故被修改为指向子类的对应方法了

		// 测试4
		System.out.println("***************");
		System.out.println("测试四:接口--与继承类似,接口与实现类之间存在多态性");
		System.out.println("***************");
		StudentSP SSP1=new StudentSP("StudentSP Li");
		SSP1.sing();SSP1.sleep();SSP1.paint();
		Singer singer1=new StudentSP("Singer Pan");
		singer1.sing();singer1.sleep();
		Painter painter1=new StudentSP("Painter Wei");
		painter1.paint();
		Painter painter2=(Painter)singer1;
		painter2.paint();
	}
}

//abstract class Person {
class Person {
	private String name;
	private int age;

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getAge() {
		return age;
	}

	
	 public void yingDa() { System.out.println("人应答……"); }
	 
	//public abstract void yingDa();
}

class Student extends Person {
	private String school;

	public String getSchool() {
		return school;
	}

	public void setSchool(String school) {
		this.school = school;
	}

	// 重写toString方法(Object)
	public String toString() {
		return (getName() + " " + getAge() + " " + getSchool());
	}

	// 重写equals方法(Object)
	public boolean equals(Object obj) {
		if (obj instanceof Student) {// 假如obj是Student对象
			Student stuTemp = (Student) obj;
			if (school == stuTemp.getSchool() && this.getName() == stuTemp.getName()
					&& this.getAge() == stuTemp.getAge()) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	public void yingDa() {
		System.out.println("学生应答……");
	}
}

class Teacher extends Person {
	public void yingDa() {
		System.out.println("老师应答……");
	}
}

class Lady{
	private String name;
	private Person per;
	Lady(String name, Person per){
		this.name=name;this.per=per;
	}
	public void ladyYingDa(){per.yingDa();}
}

// 接口1
interface Singer {
	public void sing();

	public void sleep();
}
//接口2
interface Painter{
	public void paint();
}
class StudentSP implements Singer, Painter {
	private String name;

	StudentSP(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	// 重写接口的所有方法
	public void sing() {
		System.out.println(getName() + " is singing");
	}

	public void sleep() {
		System.out.println(getName() + " is sleeping");
	}
	
	public void paint(){
		System.out.println(getName() + " is painting");
	}
}
运行结果:

***************
测试一
***************
My object's name is Mimi No. 100
My object's name is Papa No. 200
***************
测试二:继承、重写、访问权限
***************
重写toString的结果: Jhon 12 Stanford
student==student2? true
***************
测试三:动态绑定和多态
***************
学生应答……
老师应答……
老师应答……
***************
测试四:接口--与继承类似,接口与实现类之间存在多态性
***************
StudentSP Li is singing
StudentSP Li is sleeping
StudentSP Li is painting
Singer Pan is singing
Singer Pan is sleeping
Painter Wei is painting
Singer Pan is painting

多态的内存图解

(http://blog.csdn.net/scliu12345/article/details/53738185)


(转自:http://blog.csdn.Net/u013905744/article/details/44346717)

其实不是子类的的show()方法把父亲覆盖了;应该是 子类的父亲的show()指针被修改为指向子类的show()方法了, 通过指针的解释更合适点


 java基础之【继承--->多态】内存图

http://blog.csdn.net/hubiao_0618/article/details/38523281



执行流程
[objc]  view plain  copy
 print ?
  1. 1:Animal a = new Cat();  
  2.     1.1:在栈中创建区域,类型为Animal,变量名:a;  
  3.     1.2:在堆中new Cat();占用一块区域。地址值:[0x3a4]  
  4.     1.3:spuer()实例化父类Animal。  
  5.         1.3.1:new Animal();占用一块区域,地址值:0x3ab;  
  6.         1.3.2:引用着在方法区中初始化[Animal中的所有方法,该引用为:[0x754]]。  
  7.         1.3.3:将Animal()引用赋给spuer();spuer引用着Animal();  
  8.     1.4:在方法区中初始化Cat类的所有方法,引用值为0x343。  
  9.     1.5:将0x3a4赋给栈中的变量a;a就开始引用Cat()。  
  10. 2:a.eat();  
  11.     2.1:通过[0x3a4]找到Cat。  
  12.     2.2:编译时期:先spuer()找到Animal中的方法。如果没有,则报错。  
  13.     2.3:运行时:直接在Cat中找到eat(),当Cat中没有,再去Animal中找。  
  14.     2.4:将eat()方法要方法区压栈,执行,输出:SOP(猫吃鱼);  
  15. 3:a = new Dog();  
  16.     3.1:在堆new Dog(),开辟一块新区域,地址值:0x87xfds  
  17.     3.2:spuer();实例化父类Animal    
  18.         3.2.1:new Animal()开辟新区域,地址值0x33fa;  
  19.         3.2.2:成员方法引用着方法区中已初始化的[0x754];  
  20.         3.2.3:将Animal地址值0x33fa赋给spuer();;spuer引用着Animal();  
  21.     3.3:在方法区中初始化Dog类的所有方法,引用值为0x422ac。  
  22.     3.4:将[0x87xfds]赋给栈中的变量a;  a不再引用Cat,而是引用着Dog;这时堆中的Cat已成为垃圾,等待JVM空闲时来回收。  
  23. 4:a.eat();  
  24.     4.1:通过a变量引用值找到堆中标记为0x87xfds的区域。  
  25.     4.2:编译时:先进super();去检查Animal引用的方法区中有没有eat()方法,如有没有则报错。  
  26.     4.3:运行时:直接去Doa方法区中找到eat();如果Doa没有,再去执行super()调用父类的eat()方法。  
  27.     4.4:从方法区中将eat()压栈,执行(SOP('狗吃粮'))。  
  28. 5:a.shudy();  
  29.     5.1:通过a变量引用值找到堆中标记为0x87xfds的区域。  
  30.     5.2:编译时:先进super();去检查Animal引用的方法区中有没有shudy()方法,结果Animal中没有shudy()方法,所以就在编译时期就报错。  
  31. 6:Dog d = (Dog)a;  
  32.     6.1:在栈中开辟区域,存储类型为Dog,变量名d  
  33.     6.2:将a向下转型,从Animal转为Dog来引用Dog;(将a变量赋给d)  
  34.     6.3:a和d都指向堆中同一个Dog对象。  
  35. 7:d.eat();//从Dog方法中压栈执行eat()方法,然后弹栈;  
  36. 8:d.shudy();//从Dog方法中压栈执行shudy()方法,然后弹栈;  
  37. 9:Cat c = (Cat) a;  
  38.     9.1:在栈中开辟一块区域,存储类型:Cat,变量名称:c  
  39.     9.2:将a向下转型,将Anmail引用Dao转为Cat引用Dog;结果抛出类型转换异常。Dog不能被转为Cat;</span>  
总结:
   1:多态=继承+重写+父类引用子类         如:  Fu ff = new Zi();
   2:普通成员
            变量:都参考左边,因为变量不存在重写,方法中调用变量采用就近原则。
    方法:编译参考左边,运行参考右边。
   3:静态成员
          变量和方法:编译运行都参考左边;  因为静态与对象无关。成员加静态修饰的没加private,都可以被类直接调用,所以参考的都是左边。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值