JavaSE 面向对象(下) (承接上文)
二、面向对象三大特性
3 多态
-
一个对象的实际类型是确定的,但是可以指向对象的引用类型有很多。
-
多态定义:
- 同一个方法,但根据传入对象不同采用不同的行为方式
-
存在的条件:**继承关系、方法需要重写、父类引用指向子类对象!**Father f1 = new Son(); (向上转型)
- static方法,属于类,不属于实例
- final 常量池中,不能修改
- private为私有方法,故不能修改
-
多态注意:
- 多态是方法的多态,属性没有多态
- 父类和子类有联系,可以向上转型/进行类型转换!
多态案例展示1:(多态的展示!)
package com.oop.demo06;
//父类
public class Person {
public void run(){
System.out.println("Father Run!");
}
}
package com.oop.demo06;
//子类
public class Student extends Person{
@Override
public void run(){
System.out.println("Son run!");
}
}
package com.oop.demo06;
//测试类
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
Person s2 = new Student(); //可以通过父类new一个子类对象-->向上转型
//Student 能调用的方法都是自己的或者继承父类的(重写的/未重写的)
s1.run();// Son run!
//Person引用子类对象,重写run,调用子类方法;若未重写,调用父类方法
s2.run();// Son run!
//1. 若子类重写了父类中的方法,则执行子类中方法
//2. 若子类未重写父类中某方法,则执行父类中方法
//3. 子类特有的方法父类无法调用
}
}
- instanceof 和类型转换
多态案例展示2:(类型转换与instanceof的展示!)
package com.oop.demo06;
//父类
public class Person {
public void run(){
System.out.println("Father Run!");
}
}
package com.oop.demo06;
//子类
public class Student extends Person{
@Override
public void run(){
System.out.println("Son run!");
}
public void go(){
System.out.println("Go!");
}
}
package com.oop.demo06;
//测试类 (展示类型转换与instanceof用法)
public class Application {
public static void main(String[] args) {
//类型之间的转换: 父 子
//高 低
Person p = new Student();
//(student)将这个对象转换为Student类型,这样就可以使用Student中的方法!
Student s1 = (Student)p; //父类转换为子类。强制转换
s1.go();
//子类对象转换为父类对象
Student s2 = new Student();
Person p2 = s2; //子类转换为父类,向上转型。不过会丢失自己特有方法
p2.run();
}
}
//instanceof说明
/*
//System.out.println(X instanceof Y);
//编译能否通过取决于X与Y中是否有父子关系。
//Object -> Person -> Student
// -> Teacher
Object object = new Student();
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);//编译出错
*/
三、抽象类
abstract修饰的类,可以看作一个约束,子类必须遵守,或重写或再次继承给下一个子类。
- 抽象类中可以有抽象方法&普通方法
- 但是有抽象方法的类必须是抽象类
抽象类案例展示:
package com.oop.demo08;
//abstract 抽象类
//1. 不能new出这个抽象类,只能靠子类去实现它:约束!!!
//2. 抽象类中可以写普通方法。
//3. 抽象方法必须在抽象类中。
public abstract class Action {
//约束~ 有人帮我们实现~
//abstract 抽象方法,只有方法名,无方法体。
public abstract void doSomething();
public void hello(){
System.out.println("Hello World");
}
}
package com.oop.demo08;
//继承上述抽象类
public class Person extends Action {
@Override
public void doSomething() {
System.out.println("Run and run!");
}
}
四、接口
类的分类:
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范!自己无法写方法~专业的约束!约束与实现分离:面向接口编程~
- 接口的本质是契约!
接口作用:
- 约束
- 定义一些方法,让不同的人实现
- public abstract 默认修饰方法
- public static final 默认修饰常量
- 接口不能被实例化~接口中没有构造方法;
- impliments可以实现多个接口
- 子类必须要重写接口中的方法
接口案例展示:
扫描二维码关注公众号,回复:
10398580 查看本文章
package com.oop.demo09;
//interface 关键字
public interface UserService {
//接口中的所有定义都是抽象的 public
//以下方法默认带有public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package com.oop.demo09;
public interface TimeService {
void timer();
}
package com.oop.demo09;
//类可以实现接口 关键字:implements
//实现接口的类,必须重写接口中的方法
//多继承: 利用接口可以实现
public class UserServiceImpl implements UserService,TimeService{
@Override
public void timer() {
}
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
五、Static详解
-
static加在方法上为静态方法,加在属性上为静态属性。
- 静态变量通过"类名.变量名"调用;非静态变量通过"对象.变量名"调用。
- 静态方法可以通过静态方法调用;非静态方法通过对象调用。
案例展示:
package com.oop.demo07; //static public class Student { private static int age;//静态变量 private double score; //非静态变量 public void run(){ } public static void go(){ } public static void main(String[] args) { Student s1 = new Student(); System.out.println(Student.age);//静态变量调用 System.out.println(s1.score);//非静态变量调用 s1.run();//非静态方法通过实例对象调用 go();//静态方法可以调用静态方法 } }
-
匿名代码块与静态代码块
- 匿名代码块 {} //赋初始值
- 静态代码块 static{} //首先执行且只执行一次!、
案例展示:
package com.oop.demo07; //1 2 3为执行次序 public class Person { // 2 :赋初始值 { //代码块(匿名代码块) System.out.println("匿名代码块"); } // 1 :只执行一次 static { //静态代码块,类加载即执行 System.out.println("静态代码块"); } // 3 :构造器 public Person(){ System.out.println("构造方法"); } public static void main(String[] args) { Person p1 = new Person(); System.out.println("==========================="); Person p2 = new Person(); } } /*运行结果: 静态代码块 匿名代码块 构造方法 =========================== 匿名代码块 构造方法 */
六、内部类
不建议随便写内部类,会分析即可。
-
一个Java类中可以有多个class类,但是只能有一个public class类
-
匿名内部类: 例:new Apple().eat(); /. new UserService(){方法}
-
内部类可访问外部类的私有方法和属性
内部类案例展示:
package com.oop.demo10;
//外部类中包含内部类
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类的方法");
}
class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性/私有方法
public void getID(){
System.out.println(id);
}
}
}
package com.oop.demo10;
//测试类
public class Application {
public static void main(String[] args) {
//new一个Outer对象
Outer outer = new Outer();
//通过这个外部类来实例话内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}
写在最后
侧耳听智慧,专心求聪明!
To Demut and Dottie!