面向对象三大特征:封装、继承、多态
封装指的是将对象的状态信息和行为捆绑为一个逻辑单元的机制,将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。简单来说就是属性私有化,对外提供统一访问的get/set方法。
下面通过程序来理解一下封装。
public class Person { private int age;//属性私有化,这是封装的要求 private String name; //无参的构造方法,构造方法名和类名相同,默认有该构造方法 //如果写了别的构造方法,则不再自动提供该构造方法 public Person() { super(); } //有参的构造方法,可以通过this.方法访问到本来的属性 public Person(int age, String name) { super(); this.age = age; this.name = name; } //写age和name的get和set方法,我们可以使用快捷键Shift+Alt+s //然后在其中找关于get和set字样的一条,方法就会自动写好了 public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class TestPerson { public static void main(String[] args) { //通过new+构造方法的方式创建了一个Person对象 Person p = new Person(30,"李四");//这里我们直接定义了对象的年龄和名字 //通过get方法得到年龄和名字并输出 System.out.println("年龄:"+p.getAge()+",姓名:"+p.getName()); //同样可以通过一下方式定义 p.setAge(20);//设置年龄为20 p.setName("张三");//设置名字为张三 System.out.println("年龄:"+p.getAge()+",姓名:"+p.getName()); } } //运行结果 //年龄:30,姓名:李四 //年龄:20,姓名:张三
简单说了一下封装,下面说一下继承。Java继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类被称为父类。Java具有单继承的特点,每个子类只有一个直接父类。
继承有两点好处1.代码的复用,2为了以后多态的使用。
继承需要注意的地方有几点:一般的属性和方法可以被继承,构造方法不被继承,私有的方法不被继承,私有的属性被隐藏,可以通过继承来的公有方法访问。
下面通过一个程序简单理解一下继承。
//父类Person public class Person { private String name; private int age; public Person(){ } public Person(String name,int age){ this.name = name; this.age = age; } //父类的方法 public void print(){ System.out.println("姓名:"+this.name+",年龄:"+this.age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } //子类Student public class Student extends Person { private int sid; // 避免使用和父类中同样名字的属性 // private String name; // public void test(){ // this.name = "姓名"; // } public Student() { super(); } public Student(int sid) { super(); this.sid = sid; } public Student(String name, int age, int sid) { super(name, age);// 调用父类的构造方法,这样就不用写下面的两句了 // this.setName(name); // this.setAge(age); this.setSid(sid); } //重写了父类的方法,调用的时候调用重写之后的子类的方法 public void print() { System.out.println("测试"); //调用父类的方法 super.print(); } public static void main(String[] args) { // Student s = new Student("张飞",20); 构造方法不被继承。 Student s = new Student(); // s.name = "张飞";由于name是私有属性,所以不能继承 // s.print(); //通过继承来的方法来访问 s.setName("张飞"); s.setAge(20); s.print(); } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } } //执行结果 //测试 //姓名:张飞,年龄:20
下面说一下多态的概念及使用。顾名思义多态即一个对象,多种状态,父类引用指向子类的对象。
多态两点基本定理:
1. 发生多态时,只能调用父类的方法,不能调用子类的方法。
2. 发生多态时,如果子类中重写了父类的方法,再调用这个方法,调用的是子类重写之后的方法。
下面通过程序理解一下多态。
//父类Pet public class Pet{ private String name; private int age; public Pet() { super(); } public Pet(String name, int age) { super(); this.name = name; this.age = age; } public static void test(){ System.out.println("父类静态测试方法"); } public void eat(){ System.out.println("Pet:不知道吃什么"); } //重写toString方法 public String toString(){ return "姓名:"+this.name+",年龄:"+this.age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } //子类Dog public class Dog extends Pet { public static void test(){ System.out.println("子类静态方法重写"); } public void catchMouse(){ System.out.println("Dog:狗跑的快"); } //如果我们不重写子类的这个方法,默认调用的则是父类的方法 public void eat(){ System.out.println("Dog:狗吃骨头"); } public static void main(String[] args) { Pet p = new Dog();//用Pet创建了一个Dog的对象 p.eat();//由于重写了父类的方法,所以调用的是子类的 Pet.test();// 父类静态测试方法 Dog.test();//调用子类的静态方法 // p.catchMouse();//因为父类没有这个方法,所以这句话会报错 // Dog d = new Dog(); // d.catchMouse(); //这样就可以根据上面创建的p属于哪类对象而调用对应的方法 if(p instanceof Dog){//判断p是否属于Dog的类型 Dog d = (Dog)p;// 新建对象?没有新建对象 d.catchMouse(); }else if(p instanceof Cat){ Cat c = (Cat)p; c.climb(); } } } //子类Cat public class Cat extends Pet{ public void eat(){ System.out.println("Cat:猫吃鱼"); } public void climb(){ System.out.println("Cat:猫捉老鼠"); } } //执行结果,如果创建的是Cat的对象,那么结果可想而知 //Dog:狗吃骨头 //父类静态测试方法 //子类静态方法重写 //Dog:狗跑的快