面向对象02
1.static 的使用
public class Student { // 学生类 public String name; public int age; public Student() { System.out.println(" 无参......."); } // 静态代码块 执行顺序是 书写的顺序 static { System.out.println("静态代码块1"); } static { System.out.println("静态代码块2"); } // 在实例化对象之前 执行的 普通代码块 执行顺序是 书写的顺序 { System.out.println("普通代码块1"); } { System.out.println("普通代码块2"); } }
public class StudentTest { static int num; public static void main(String[] args) { /** * 观察 静态代码块 普通代码块 和 无参构造方法的执行顺序 */ Student stu = new Student(); // num必须是static修饰的才能调用 System.out.println(num); } public void sayHello() { // 普通方法中调用了 静态变量 System.out.println(num); } }
2.static 实现 投票
public class Student { // 学生类 public String name; public int age; /** * 定义学生可以投票的数量 * static 让所有的对象 共享这一个变量 */ public static int tickets = 100; // 带参构造 public Student(String name, int age) { super(); this.name = name; this.age = age; } /** * 定义一个投票的方法 */ public void getTickects() { System.out.println("感谢您的参与!剩余票数:" + (--tickets)); } }
public class StudentTest { public static void main(String[] args) { Student stu1 = new Student("小黑1", 30); Student stu2 = new Student("小黑2", 40); Student stu3 = new Student("小黑3", 50); System.out.println("第1个姓名:" + stu1.name); System.out.println("第2个姓名:" + stu2.name); System.out.println("第3个姓名:" + stu3.name); System.out.println("开始投票*******************"); // 调用投票的方法 stu1.getTickects(); stu1.getTickects(); stu2.getTickects(); stu3.getTickects(); } }
通过类名可以直接访问 类中的静态属性或者方法!
3.封装
/** * static: * 01.修饰变量 或者方法 属于 类 * 02.在类被加载的时候 就执行了! 并且只执行一次! * 03.非静态的方法中可以直接访问 静态方法或者静态属性 * 04.静态的方法中不可以直接访问 非静态方法或者非静态属性 * 05.普通的方法不能定义 静态属性 * * 面向对象的三大特性: * 1.封装 隐藏内部细节! 安全! * 01.属性私有化 其他的类访问不了! * 02.创建供外部访问的接口! get(取值) 和 set(赋值)方法 * 03.在 set()中书写 逻辑判断 * * 2.继承 * 3.多态 * * */ public class Student { // 01.属性私有化 private String name; private int age; private String sex; // 性别 /** * 02.创建供外部访问的接口! get(取值) 和 set(赋值)方法 * * alt +shift + s +r */ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } // 在 set()中书写 逻辑判断 public void setAge(int age) { // 如果age<0 或者大于150 if (age < 0 || age > 150) { System.out.println("因为是不健康的输入!我们给您默认值!"); this.age = 50; // 默认值 } else { this.age = age; } } public String getSex() { return sex; } // 做逻辑判断 public void setSex(String sex) { if (sex.equals("男") || sex.equals("女")) { this.sex = sex; } else { this.sex = "男"; } } // 无参构造 public Student() { super(); } // 带参构造 public Student(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } }
public class StudentTest { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 通过无参构造创建一个学生对象 Student stu = new Student(); System.out.println("请您输入姓名:"); // 把用户的输入直接赋值给 对象的name属性 stu.setName(scanner.next()); System.out.println("请输入您的年龄:"); stu.setAge(scanner.nextInt()); System.out.println("请输入您的性别:(男/女)"); stu.setSex(scanner.next()); System.out.println("您的姓名是:" + stu.getName()); System.out.println("您的年龄是:" + stu.getAge()); System.out.println("您的性别是:" + stu.getSex()); } }
4.继承
/** * 所有动物的父类 */ public class Animal { /** * 定义属性 */ private String name; // 姓名 private int health; // 健康值 /** * protected修饰的属性 在子类中可以访问 无论子类和父类 是否在相同的一个包中! * 并不是 子类的对象 可以访问! * protected String strain; // 品种 */ public Animal() { System.out.println("Animal的无参构造"); } public Animal(String name, int health) { System.out.println("Animal的带参构造"); this.name = name; this.health = health; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } }
public class Dog extends Animal { private String strain; // 子类特有的属性 品种 public void sayHello() { System.out.println("这是" + this.getName() + " 打招呼的 方法!"); } /** * super()!调用父类的无参构造 * super(String,int)调用父类的带参构造 * 上面两个只能在子类的构造方法中书写,必须位于第一行! * super. 这相当于 父类的对象! * this. 相当于本类的对象! * 可以出现在非静态的方法中! * super不能访问访问父类 私有的属性或者方法 * * 我们如果实例化子类对象!没有显示的调用父类的代参构造! * 那么 都会执行父类的无参构造! * */ public Dog() { System.out.println("Dog 的无参构造方法"); } public Dog(String strain) { super("小黑黑", 200); System.out.println("Dog 的带参构造方法"); this.strain = strain; } public String getStrain() { return strain; } public void setStrain(String strain) { this.strain = strain; } }
/** * java单根继承性 extends 实现代码的复用! * * 子类和父类 满足 is -a 的关系! * 小狗是动物! * 小猫是动物! * * 子类中能继承父类的什么? * 01.非私有的属性以及方法! * 02.父类的构造方法 不允许被继承! * */ public class AnimalTest { public static void main(String[] args) { Dog dog = new Dog("金毛"); } }
5.重写
public class Animal { // 每个动物都有吃饭 public void eat() { System.out.println("父类animal吃东西的方法......"); } // 验证返回值 public Animal getAnimals() { return new Animal(); } // 验证父类的静态方法 子类不能重写 public static void testStatic() { System.out.println("父类的静态方法"); } }
public class Cat extends Animal { /** * 方法重写 * 01.不同类! 子类重写父类的方法 * 02.方法名相同,参数列表也要相同! * 03.访问修饰符不能严于父类! * 04.如果父类方法的返回值 是一个父类, * 那么子类中重写的方法 可以是父类的子类! * 05.父类的静态方法不能被重写!但是方法名 可以 一致 * 06.父类私有的方法 也不允许 被重写! */ public void eat() { System.out.println("小猫咪 吃鱼......."); } // 验证返回值 是 子类也可以 public Cat getAnimals() { return new Cat(); } public static void testStatic() { System.out.println("子类的静态方法"); } }
6.重写equals方法
public class Student { private String name; private String sex; private int age; // 重写equals public boolean equals(Object o) { if (this == o) { //先判断内存地址 return true; } if (!(o instanceof Student)) { //判断类型 return false; } // 向下转型 Student student = (Student) o; if (this.age == student.getAge() && this.name.equals(student.getName()) && this.sex.equals(student.getSex())) { return true; } else { return false; } } public Student(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public Student() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public class TestStudent { public static void main(String[] args) { Student stu1 = new Student("小黑", "男", 50); Student stu2 = new Student("小黑", "男", 50); Student stu3 = stu2; System.out.println(stu1 == stu2); // false System.out.println(stu2 == stu3); // 重写我们equals 只要是 student类中的各个属性相等 我们就让两个对象相等 System.out.println(stu2.equals(stu1)); //true } }
7.多态的使用
public class Animal { private String name; // 姓名 private int health; // 健康值 public Animal() { } public Animal(String name, int health) { this.name = name; this.health = health; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHealth() { return health; } public void setHealth(int health) { this.health = health; } // 父类的方法 public void gotoHospital() { } }
public class Master {// 主人类 // 给宠物看病的方法 public void gotoHospital(Animal animal) { if (animal instanceof Dog) { animal.gotoHospital(); animal.setHealth(100); } if (animal instanceof Cat) { animal.gotoHospital(); animal.setHealth(100); } } }
public class Dog extends Animal { private String strain; // 子类特有的属性 品种 // 子类重写父类的方法 @Override public void gotoHospital() { System.out.println("小狗狗看病...."); } public Dog() { } public Dog(String strain) { super("aa", 12); this.strain = strain; } public String getStrain() { return strain; } public void setStrain(String strain) { this.strain = strain; } }
public class Cat extends Animal { private String sex; public Cat() { super(); } // 子类重写父类的方法 @Override public void gotoHospital() { System.out.println("小猫咪看病...."); } public Cat(String sex) { super(); this.sex = sex; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
/** * 多态: * 不同的对象,去做同一件事情,产生了不同的结果! * * 主要分两种: * 01.编译时的多态 (方法重载) * sayHello(Student stu) * sayHello(Teacher stu) * sayHello(Animal stu) * 02.运行时的多态 * java在运行期间,根据调用方法的类型,来决定使用哪个对象的方法!! * * 多态存在的三个条件: * 01.要有继承关系 * 02.要有方法的重写 * 03.父类的引用指向了 子类的对象 * */ public class AnimalTest { public static void main(String[] args) { // 父类的引用指向了 子类的对象 Animal dog = new Dog("金毛"); dog.setName("小金"); dog.setHealth(42); Animal cat = new Cat("女"); cat.setName("小花"); cat.setHealth(45); Master master = new Master(); master.gotoHospital(dog); System.out.println("小gougou的健康值:" + dog.getHealth()); } }
一道多态的面试题
public class A { public String show(D d) { return " A and D"; } public String show(A a) { return " A and A"; } }
public class B extends A { public String show(B b) { return " B and B"; } public String show(A a) { return " B and A"; } }
public class C extends B { }
public class D extends B { }
public class Test { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); // 父类的引用 指向了 子类的对象 B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); System.out.println(a1.show(c)); System.out.println(a1.show(d)); System.out.println(a2.show(b)); System.out.println(a2.show(c)); System.out.println(a2.show(d)); System.out.println(b.show(b)); System.out.println(b.show(c)); System.out.println(b.show(d)); // B类中没有方法 回去 父类中查询 有没有对应的方法 } }