面向对象编程
面向过程: C
面向对象: JAVA、C#
对象:一切皆对象,对象由属性(名词,描述对象的特征)-成员变量 和行为组成(动词,描述对象的行为)-方法
类:具有相同属性和方法的一组对象的集合,也可以说类是对象的模版
类是抽象的,对象是具体的 //只有main方法所在的类是public的,当使用java的类时要导包,lang包底下的类无需导包
构造方法:
1、 名称和类名相同
2、 没有任何的返回值类型,连void也没有
3、 每一个类都有一个默认的空的隐式构造方法: 类名(){}
4、 如果手动地去写一个显式的构造方法,隐式的构造方法就不存在了
5、 构造方法的作用是用来创建对象的,不能调用;构造方法还可用来初始化成员变量。如:
public class Test{ public static void main(String args[]){ Person p1 = new Person("张三",20); Person p2 = new Person("李四",19); System.out.println(p1.name); System.out.println(p2.name); } } class Person{ String name; int age; Person(String name,int age){ this.name = name; this.age = age; } } //局部变量和成员变量同名时,要用this关键字来区分,this表示当前对象的引用(即this代表成员变量)
调用方法:对象.方法名();
例:1.Tom抓住了Jerry, Jerry哭了
public class Test{ public static void main(String args[]){ Cat cat = new Cat(); cat.name="Tom"; Mouse mouse = new Mouse(); mouse.name = "Jerry"; cat.catchMouse(mouse); } } class Cat{ String name; public void catchMouse(Mouse m){ m.cry(); } } class Mouse{ String name; public void cry(){ System.out.println(name+" is crying"); } }
2.张三吃了李四的一根头发
public class Test{ public static void main(String args[]){ Person p1 = new Person(); p1.name = "张三"; Person p2 = new Person(); p2.name = "李四"; p1.eat(p2.hair); } } class Person{ String name; Hair hair; public void eat(Hair h){ } } class Hair{ }
= 符号比较的是栈里面的内容(对象的引用),静态区的特点:保存的数据不重复
equals方法比较的是堆区中的内容是否相等
String str1 = new String(“aaa”); String str2 = new String(“aaa”);
str1与str2不相等,因为地址不同。
String str1 = “aaa”;
String str2 = “aaa”;
str1和str2相等,因为不是new出来的,是保存在静态区的常量。
static关键字:可以修饰变量,也可以修饰方法。
静态变量(类变量):所有对象共享,调用时直接: 类名.变量名
静态方法(类方法):无需创建对象,直接调用方法 注:静态的方法不能访问非静态的成员变量,而非静态的方法既可以访问静态的成员变量又可以访问非静态的成员变量
main方法为static的原因:main方法为程序的入口,若非static的话,则要先创建对象然后才能调用main方法
java要求的是类取名应该是独一无二的,Java的包机制用来使类名不重复,类的全名为包名+类名。规范:域名倒过来写:com.xxx.xxx.xxx
面向对象的三大基本特征:
封装:代码的复用,屏蔽底层细节
继承:代码的复用,表示类与类之间的关系,什么是一种什么 关键字:extends
A extends B ,B成为父类、基类或超类。 子类自动拥有父类的所有成员
Java中继承是单继承(只有一个父类),区别于C++的多继承(可以是多个父类)
多态:动态绑定,池绑定;在程序运行的过程中传入实际参数调用相应的方法。 1、继承 2、方法的重写 3、父类的引用指向子类的对象
例:
public class Test{ public static void main(String args[]){ Animal a = new Cat(); Person p = new Person(); p.playWithAnimal(a); } } interface Animal{ public void enjoy(); } class Cat implements Animal{ public void enjoy(){ System.out.println("cat enjoy"); } } class Dog implements Animal{ public void enjoy(){ System.out.println("dog enjoy"); } } class Person { public void playWithAnimal(Animal a){ a.enjoy(); } }
访问修饰符
public: 公共的(能在任何情况下使用)
protected: 受保护的(即使不在同一包下,子类中可以调用)
default: 默认的,相当于没有写访问修饰符(在同一个包底下可以使用)
private: 私有的(只能在类里面使用)
★方法的重写(overwrite/override)/覆盖:发生在继承关系中,子类中重写的方法和父类中被重写的方法必须具有相同的返回值类型、相同的方法名、相同的参数列表;子类中重写的方法不能有比父类中被重写的方法更严格的访问修饰符
1、在子类重写的方法要调用父类被重写的方法2、子类中访问父类同名的成员变量时3、在子类的构造方法中要调用父类的构造方法的时候使用super关键字 如:
public class Test{ public static void main(String args[]){ Dog d = new Dog(); d.sleep(); } } class Animal{ String name; public void sleep(){ System.out.println("Animal is sleeping"); } } class Dog extends Animal{ String name; public void sleep(){ super.sleep(); //先构建父类对象然后放到子类对象里面 System.out.println("Dog is sleeping"); } }
3、在子类的构造方法中要调用父类的构造方法的时候
在创建子类对象时,Java默认会调用父类无参数的构造方法先创建出父类的对象,若父类中重写成了有参数的构造方法时,应该在子类中手动调用有参数的构造方法。
public class Test{ public static void main(String args[]){ Dog d = new Dog(); d.sleep(); } } class Animal{ String name; Animal(String name){} public void sleep(){ System.out.println("Animal is sleeping"); } } class Dog extends Animal{ String name; Dog(){ super("a"); } public void sleep(){ super.sleep(); System.out.println("Dog is sleeping"); } }
注:利用super()调用父类的构造方法时,要放在子类构造方法的第一句话。
Java中所有类继承自Object类。
自动调用toString 方法的情况:1、System.out.println()方法中,若打印的是Object类型,则打印出的是类名+@+HashCode 2、在遇到字符串连接符(+)时
要比较两个自定义类,要重写equals()方法,来给出比较的规则。 如:
public class Test{ public static void main(String args[]){ Person p1 = new Person(); p1.name = "a"; p1.age = 19; Person p2 = new Person(); p2.name = "a"; p2.age = 18; System.out.println(p1.equals(p2)); } } class Person{ String name; int age; public int hashCode(){ return name.hashCode(); } public boolean equals(Object obj){ if(obj instanceof Person){ Person p = (Person)obj; if(this.name==p.name){ return true; } else{ return false; } }else{ return false; } } }
注:重写equals方法后要重写hashCode方法以保持hashCode一致;相等的对象有相同的哈希码,具有相同哈希码的对象不一定相等。(哈希码无序,查询速度最快)
★ 方法的重载(overload):在调用方法时,根据传入的实际参数来载入相应的方法。
在同一个类中,重载的方法和被重载的方法必须具有相同的方法名,可以具有不同的返回值,但必须具有相同的参数列表
例:
public class Test{ public static void main(String args[]){ T t = new T(); t.test(5,10,10); } } class T{ public void test(int m,int n){ System.out.println(m+n); } public void test(int m,int n,int x){ System.out.println(m+n+x); } }