`
Swifly
  • 浏览: 13411 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

三、面向对象

阅读更多
1. 面向对象编程语言特征:隐藏(封装)、继承、多态。
2. 概念:
    类:类是用于描述同一类型的对象的一个抽象概念。
    对象:可以看成该类的一个具体实例,是java程序的核心,在java程序中“万事万能物皆对象”。
3. 类之间的关系:依赖、关联、聚合、合成、泛化、实现。
4. 值传递:基本类型传递的是该数据值本身。引用类型传递的是对对象的引用,而不是对象本身 。
5. 构造方法:和类同名 / 没有返回值 不能写void / 如果没有则自动添加 /如果有就不再自动添加
class Person{
	int id;
	int age;
	Person(){
		
	}//如果自己定义了一个构造方法,那么这个默认的构造方法将不再有,需要自己写上
	Person(int id,int age){
		this.id = id;
		this.age = age;	
	}	//除了static方法以外的其它方法都将自动生成一个this变量指向本身引用的对象
	public void setAge(int age){
		this.age = age;
	}
}
public class TestPerson{
	public static void main(String [] args){
		Person p1 = new Person();
		Person p2 = new Person();
		Person p3 = new Person(3,23);
		int age = 25;
		p1.setAge(age);
		p2.setAge(age++);
		p3.setAge(++age);
		System.out.println(p1.age);
		System.out.println(p2.age);
		System.out.println(p3.age);
	}
}

6. 方法的重载:方法名字一样,参数不一样 | 个数 / 类型 。(构造方法也可以重载)
   如果方法名是类名,但被void修饰,则只是一个普通方法而已。
    方法调用时按就近原则。
//方法的重载是指一个类中可以定义有相同的名字,但参数不同的多个方法。 
//返回值不同不构成方法的重载
//调用时,会根据不同的参数表选择对应的方法。

//与普通方法一样,构造方法也可以重载:
class OverLoad{
		int i;
		char c = '*';
		OverLoad(){
		
		}
		OverLoad(int i){
			this.i = i;
		}
		OverLoad(char c){
			this.c = c;
		}
		OverLoad(int i ,char c){
			this.i = i ;
			this.c = c;
		}
		OverLoad(char c,int i){
			this.i = i ;
			this.c = c;
		}
		public void disPlay(){
			System.out.println("int i = "+i+"  char c = "+c);
		}
}
class Test{
	public static void main(String [] args){
		int i = 3;
		char c = 'c';
		OverLoad o1 = new OverLoad();
		OverLoad o2 = new OverLoad(i);
		OverLoad o3 = new OverLoad(c);
		OverLoad o4 = new OverLoad(c,i);
		OverLoad o5 = new OverLoad(i,c);
		o1.disPlay();
		o2.disPlay();
		o3.disPlay();
		o4.disPlay();
		o5.disPlay();
	}
}

7. this
//在类的方法定义中使用的 this 关键字代表使用该方法的对象的引用。
//当必须指出当前使用方法的对象是谁时要使用this。
//有时使用this可以处理方法中成员变量和参数重名的情况。
//this可以看作是一个类中的变量,它的值是当前对象的引用

class Leaf{
	int i = 0 ;
	Leaf(){
	
	}
	Leaf(int i){
		this.i = i;	
	}	
	public Leaf increament(){
		this.i++;
		return this;
	}
	public void print(){
		System.out.println(this.i);	
	}
}
class Test{
	public static void main(String [] args){
		Leaf l1 = new Leaf();
		Leaf l2	= new Leaf(3);
		l2.increament().increament().print();
	}	
}

8. static
//在类中,用static声明的成员变量为静态成员变量,
//静态成员变量在类被装载的时候被初始化
//它为该类的公用变量,对于该类的所以对象来说,static成员变量只有一份。
//可以通过对象引用或类名(不需要实例化)访问静态成员。

//用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。


//非静态初始化块,构造方法的一部分,不常用。

class Cat{
	static int sid;
	private String name;
	static A a = new A();//静态的,只在第一次new一个对象时会被装载
	static{
		b = new B();
	}
	static B b;
	C c = new C();//非静态的,每次new一个对象都会被装载;就像是构造方法中一部分
	{
		System.out.println("haha....");	
	}//每次new一个对象都会被装载;就像是构造方法中一部分
}
class Test{
	public static void main(String [] args){
			Cat mimi = new Cat();
			Cat.sid = 3;
			System.out.println("Cat.sid = "+ Cat.sid);
			mimi.sid = ++Cat.sid;			
			System.out.println("mimi.sid = "+ mimi.sid);
			mimi.sid = Cat.sid++;//注意这里,执行完成后值不变
			System.out.println("sid = "+ mimi.sid);	
			Cat pipi = new Cat();			
	}	
}
class A{
	A(){
		System.out.println("A()......");	
	}
}
class B{
	B(){
		System.out.println("B()......");	
	}
}
class C{
	C(){
		System.out.println("C()......");	
	}
}

9. package 和 import语句
    把类放到包里, 第一句话加package,包名一般公司域名倒过来
  编译好的class文件必须位于和包的层次一样的目录中
  类不一定放在同一个classpath下。
  同一个包中的类直接使用,不必引入。
  Jar文件可以当成目录看待
    如果将一个类打包,则使用该类时,必须使用该类的全名(例如:com.sxt.MyClass),Java编译器才会在找到该类。
    也可以使用 import 在文件的开头引入要使用到的类;
    可以不需要用import语句直接使用 java.lang 包中的类

10. 类的继承
    Java 中使用 extends 关键字实现类的继承机制,通过继承,子类自动拥有了基类(superclass)的所有成员(成员变量和方法)。Java只支持单继承,不允许多继承:
一个子类只能有一个基类   一个基类可以派生出多个子类
11. 访问权限
    成员变量和成员方法有4种访问权限修饰符:Private / default / protected / public /
    类有两种访问权限修饰符 public / default
    关于在位于不同包的子类中访问父类的protected成员:只有子类引用指向当前子类对象或子类中直接使用时才可以访问。
12. 方法重写
    重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型(最好去copy)
    重写方法不能使用比被重写方法更严格的访问权限,原因和多态有关
    重写方法不能使用比被重写方法更严格的访问权限。
//方法重写必需和被重写方法具相同方法名称、参数列表和返回类型(最好去copy)
//@Override  可以让javac帮助检查是否有写错
//重写方法不能使用比被重写方法更严格的访问权限,原因和多态有关
//子类重写父类的方法可以改变返回值。返回值可以改变为返回父类返回值的子类,但不能返回父类返回值的父类

class Person{
	private String name;
	private int age;
	public void setName(String name){
		this.name = name;	
	}	
	public void setAge(int age){
		this.age = age;	
	}
	public String getName(){
		return name;	
	}
	public int getAge(){
		return age;	
	}
	public void getInfo(){
		System.out.println("Name = "+this.name + "\nAge = " + this.age);	
	}
	public static Person getO(Object o){
		System.out.println("aaaaaaaaa");
		return (Person)o;	
	}
}
class Student extends Person{
		private String school;
		public void setSchool(String school){
			this.school = school;	
		}
		public String getSchool(){
			return school;	
		}
		public void getInfo(){
			System.out.println("Name = " + this.getName() + "\nAge = " + this.getAge() + "\nSchool = " + this.school);	
		}
		public static Student getO(Object o){
			System.out.println("iiiiiiiiiiiiiiiii");
			return (Student)o;	
		}
}
class Test{
	public static void main(String [] args){
		Person person = new Person();
		Student student = new Student();
		person.setName("Swifly");
		person.setAge(22);
		student.setName("cyf783");
		student.setAge(23);
		student.setSchool("sxt");
		//person.getInfo();
		//student.getInfo();
		Person s = new Student();
		s.setName("nono");
		s.setAge(21);
		Student s2 = (Student)s;//对象转型
		s2.setSchool("bjsxt");//实现多态:1.有继承;2.有重写;3.父类对象指向子类对象。
		//s.getInfo();	
		Person pp =	student.getO(s);//person 为Person类
		pp.getInfo();
	}	
}

13. super
    在Java类中使用super来引用父类的成员变量或成员方法
14. 继承中的构造方法
    构造方法没有继承
    子类的构造方法必须调用父类的构造方法。
    如果子类的构造方法中没有显式地调用父类构造方法,则系统默认调用父类无参数的构造方法。
    子类可以在自己的构造方法中使用super(……) 显式调用父类的构造方法。(更灵活了)
    对super(……) 的调用必须是构造函数中的第一个语句
    可以使用this(agument list)调用本类另外的构造方法
    对 this 的调用必须是构造函数中的第一个语句
    如果子类构造方法中既没有显式调用基类构造方法,而基类中又没有无参的构造方法,则编译出错。
15. 继承中构造方法的调用顺序
    父类的构造方法先执行。如果还有父类,那么父类的父类的构造方法先执行
    如果有静态成员变量。类被装载的时候被初始化
    成员变量,在每次执行构造方法之前被初始化
16. Object类:是所有java类的根基类
    toString、equles的重写(注意不要写错,最好还是copy)
17. 关于字符串
//String s3 = "hello";在字符串池里分配一个对象。
//String s1 = new String ("hello");一共两个对象,一个在池子里,一个在堆里。
//intern方法确保返回池子里的对象。
//比较复杂的情况,jvm就不再尝试在内存里重用对象了。
//String s6 = s3 + s4 ,对象分配到堆。(引用参与计算)
//String s7 = "hello" + "hello" ,对象分配到字符串池

class Test{
	public static void main(String [] args){
		String s1 = new String("hello");
		String s2 = new String("hello");
		String s3 = "hello";
		String s4 = "hello";
		String s5 = "hellohello";
		String s6 = "hello"+s3;
		String s7 = "hello"+"hello";
		System.out.println(s1 == s2);						//false
		System.out.println(s1.equals(s2));			//true
		System.out.println(s3 == s4);						//true
		System.out.println(s1.equals(s3));			//true
		System.out.println(s5 == s7);						//true
		System.out.println(s5.equals(s7));			//true
		System.out.println(s5 == s6);						//false
		System.out.println(s5.equals(s6));			//true	
		System.out.println(s3 == s1.intern());	//true
		System.out.println(s5 == s6.intern());	//true
		System.out.println(s6 == s7.intern());	//false

	}	
}

18. 对象转型
    一个基类的引用类型变量可以“指向”其子类的对象。
    一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)。
    可以使用 引用 变量 instanceof 类名 来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。
    子类的对象可以当作基类的对象来使用称作向上转型(upcasting),反之称为向下转型(downcasting)
19. 多态
    概念:动态绑定是指“在执行期间(而非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
    多态的存在要有3个必要条件:要有继承,要有重写,父类引用指向子类对象
    特殊情况:1成员变量(包括静态)没有多态、2私有方法没有多态、3静态方法没有多态
    通过super调用父类的方法(包括普通方法和构造方法),如果父类的方法调用了另外一个方法。另外这个方法又被子类重写了。那么有多态。(在子类直接靠super调用被重写的方法,没有多态)
//动态绑定是指“在执行期间(而非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
//多态的存在要有3个必要条件:要有继承,要有重写,父类引用指向子类对象

//成员变量有没有多态  没有
//静态方法有没有多态  没有
//私有方法有没有多态  没有
//通过super调用父类的方法(包括普通方法和构造方法),如果父类的方法调用了另外一个方法。另外这个方法又被子类重写了。那么有多态。
class Animal{
	String name;
	int i = 10 ;
	static void m(){
		System.out.println("10");	
	}
	private void n(){
		System.out.println("10");	
	}
	Animal(){
		enjoy();
	}
	Animal(String name){
		this.name = name;
	}	
	public void enjoy(){
		System.out.println("大吼。。。");
	}
}
class Dog extends Animal{
	String furColor;
	int i = 20;
	static void m(){
		System.out.println("20");	
	}
	private void n(){
		System.out.println("20");	
	}
	Dog(){
	}
	Dog(String name,String furColor){
		super(name);
		this.furColor = furColor;
	}	
	public void enjoy(){
		System.out.println("Wo..Wo...");
	}
}
class Cat extends Animal{
	String eyesColor;
	Cat(){
	}
	Cat(String name,String eyesColor){
		super(name);
		this.eyesColor = eyesColor;
	}	
	public void enjoy(){
		System.out.println("mo..mo...");
	}
}
class Bird extends Animal{
	Bird(){
		
	}
		
	public void enjoy(){
		System.out.println("zhi..zhi...");
	}
}
class Lady{
	String name;
	Animal pet;
	Lady(){
	}
	Lady(String name,Animal pet){
		this.name = name;
		this.pet = pet;
	}
	public void game(){
		pet.enjoy();	
	}
}
class Test {
	public static void main(String [] args){
	/*
		Dog d = new Dog("dog","blue");
		Lady l1 = new Lady("lili",d);	
		Animal a = new Dog("d","d");
		l1.game();
		
		System.out.println(d.i);
		Animal a = d;
		System.out.println(a.i);
		
		d.m();
		a.m();
		
//	d.n();
//	a.n();
		
		Cat c = new Cat("cat","yellow");
		Lady l2 = new Lady("MMM",c);	
		l2.game();
	*/
		new Bird();
	}
}

20. 抽象类
    用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。
    含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。如果重写不了,应该声明自己为抽象。
    抽象类不能被实例化。
    抽象方法只需声明,而不需实现。
21. final
    final的成员变量的值不能够被改变
     final的方法不能够被重写
     final的类不能够被继承
22. 接口
    java中一个类只能有一个父类,所以用接口可以实现多继承的逻辑
    接口是一种特殊的抽象类,接口中只包含常量和方法的定义,而没有变量和方法的实现。
  接口中声明的属性默认为 public  static  final 的;也只能是 public static final 的;
  接口中只能定义抽象的方法,而且这些方法默认为public的、也只能是public的;
  当一个类实现一个接口时,它必须实现接口中定义的所有方法
  如果没有实现接口中定义的所有方法,那么这个类只能是抽象的。
  多个无关的类可以实现同一个接口。
  一个类可以实现多个无关的接口。
  与继承关系类似,接口与实现类之间存在多态性。
  接口可以继承其它的接口,并添加新的属性和抽象方法。
    接口描述的是不相关的类的相同行为,而不需要考虑这些类之间的层次关系。
  优先使用接口还是抽象类?
  除非业务逻辑上有明显的继承关系,否则优先使用接口。
  有共同的代码需要在继承层次中上移,则使用抽象的父类。
//接口(interface)是抽象方法和常量值的定义的集合。
	//接口中声明的属性默认为 public  static  final 的;也只能是 public static final 的;
	//接口中只能定义抽象方法,而且这些方法默认为public的、也只能是public的;
//从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
//接口可以多重实现;
//接口可以继承其它的接口,并添加新的属性和抽象方法。
//多个无关的类可以实现同一个接口。
//一个类可以实现多个无关的接口。
//与继承关系类似,接口与实现类之间存在多态性。
//定义Java类的语法格式:
interface  Singer{
	int i = 9;			//默认(也只能)为public static final
	void sing();		//默认(也只能)为public 
	void sleep();	
}
interface  Painter{
	void paint();
	void eat();	
}
class Teacher implements Singer,Painter{
	private String name;
	public void setName(String name){
		this.name = name;	
	}
	public String getName(){
		return name;
	}
	public void teach(){
		System.out.println("注意了,上课时间到~!");	
	}	
	public void sing(){
		System.out.println("老师要唱歌了。。。");
	}
	public void sleep(){
		System.out.println("老师要睡觉了。。。");
	}
	public void paint(){
		System.out.println("老师要画画了。。。");
	}
	public void eat(){
		System.out.println("老师要吃饭了。。。");
	}
}
class Student implements Singer{
	private String name;
	public void setName(String name){
		this.name = name;	
	}
	public String getName(){
		return name;
	}
	public void study(){
		System.out.println("又要上课了~!");	
	}	
	public void sing(){
		System.out.println("学生要唱歌了。。。");
	}
	public void sleep(){
		System.out.println("学生要睡觉了。。。");
	}
}
class Test{
	public static void main(String [] args){
			Singer s = new Student();
			s.sing();
			s.sleep();
			Student ss = (Student)s;
			ss.study();
			
			Painter p = new Teacher();
			p.paint();
			p.eat();
			Singer pp = (Singer)p;
			pp.sing();
			pp.sleep();
			Teacher t = (Teacher)p;
			t.teach();
	}	
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics