java面向对象三大特性:继承、多态、封装
多态
1、一个事物多种形态
2、多态体现在类的继承和接口的实现
3、最终体现形态为父类引用指向子类对象;父类的引用只能调用父类有的成员,对子类新增的内容不可见
4、调用方式:
成员变量:编译运行均看父类
成员方法:编译看父类,运行看子类
public class PolyDemo01 {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.name);
p.eat();
//父类引用指向子类对象
Person p1 = new Student();
System.out.println(p1.name);
//此处的调用的eat是子类的方法
p1.eat();
}
}
class Person{
String name = "小头爸爸";
String gender;
void eat() {
System.out.println("父类方法-吃饭呢");
}
}
class Student extends Person{
String name = "大头儿子";
int id = 1234;
void eat() {
System.out.println("子类方法-吃饭呢");
}
void study() {
System.out.println("子类方法-学习呢");
}
}
转型
1、基本数据类型
小范围–>大范围:向上转型,自动
大范围–>小范围:向下转型,需要强制转换
2、引用数据类型
小范围–>大范围:向上转型,自动
大范围–>小范围:向下转型,需要强制转换
注意:多态前提下,父类引用指向子类对象,父类引用只能调用父类的成员,如果想要调用子类新增的成员,需要强制向下转型
封装
3、引用类型转型时,可以与instanceof一起使用,预防类型转换异常
//判断p1是否是Student类型
if(p1 instanceof Student) {
//将父类引用p1转换成Student类型
Student p2 = (Student)p1;
//转换后可以调用子类新增的成员
p2.study();
System.out.println(p2.id);
}
封装
1、隐藏内部实现细节,对外提供公共的访问方式
2、封装的优点:
提供代码安全性
提供代码复用性
public class Student {
private String name;
private int age;
private int id;
public void setName(String name) {
this.name=name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return this.age;
}
public void setId(int id) {
this.id=id;
}
public int getId() {
return this.id;
}
}
public class Test {
public static void main(String[] args) {
Student s = new Student();
s.setName("luka");
s.setAge(23);
s.setId(34244);
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println(s.getId());
}
}
抽象abstract
1、抽象方法:
(1)被abstract修饰的方法,必须定义在抽象类中
(2)抽象方法没有方法体
2、抽象类:
(1)被abstract修饰的类
(2)抽象类不能被实例化
(3)子类必须重写父类中所有的抽象方法,才可以实例化;实现部门抽象方法的子类仍是抽象类
(4)抽象类中可以有抽象类也可以有非抽象成员
注意:abstract不能与final static private native一起使用
public abstract class SportMan {
abstract void run();
abstract void sleep();
public void game() {
System.out.println("运动员要参加竞赛");
}
}
public class Runner extends SportMan{
@Override
void run() {
System.out.println("短跑运动员");
}
@Override
void sleep() {
System.out.println("短跑运动员在休息");
}
public void info() {
System.out.println("我是一名职业短跑员");
}
public static void main(String[] args) {
Runner r = new Runner();
r.run();
r.sleep();
r.info();
r.game();
}
}
权限修饰符
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1QTN4MTNzEjM3IzMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1、只有public和default可以修饰类,其他只能修饰成员
2、被private修饰的方法不能被继承,不能被重写
3、protected成员,不同包下的类访问时,需要有子类继承父类
本类:
package modifier;
public class ModifierDemo01 {
public int a = 12;
int b = 13;
protected int c = 14;
private int d = 15;
public void print() {
System.out.println("public方法");
}
void print1() {
System.out.println("default方法");
}
protected void print2() {
System.out.println("protected方法");
}
private void print3() {
System.out.println("private方法");
}
public static void main(String[] args) {
ModifierDemo01 m = new ModifierDemo01();
System.out.println(m.a);
System.out.println(m.b);
System.out.println(m.c);
System.out.println(m.d);
m.print();
m.print1();
m.print2();
m.print3();
}
}
同包下
package modifier;
//同包下其他类,private成员不能被访问
public class ModifierDemo02 {
public static void main(String[] args) {
ModifierDemo01 m = new ModifierDemo01();
System.out.println(m.a);
System.out.println(m.b);
System.out.println(m.c);
m.print();
m.print1();
m.print2();
}
}
不同包
package object;
import modifier.ModifierDemo01;
//不同包下的非子类 只有public成员可以被访问
public class ModifierDemo03 {
public static void main(String[] args) {
ModifierDemo01 m = new ModifierDemo01();
System.out.println(m.a);
m.print();
}
}
//不同包下的子类
package object;
import modifier.ModifierDemo01;
public class ModifierDemo04 extends ModifierDemo01{
public static void main(String[] args) {
//不同包下的子类,通过父类对象只能访问父类的public成员;通过子类对象可以访问public protected修饰的成员
ModifierDemo01 m = new ModifierDemo01();
System.out.println(m.a);
m.print();
System.out.println("=====================");
ModifierDemo04 m4 = new ModifierDemo04();
System.out.println(m4.a);
System.out.println(m4.c);
m4.print();
m4.print2();
System.out.println("=====================");
m4.out();
}
//不同包下的子类成员方法可以自己访问父类public projected成员
public void out() {
System.out.println(a);
System.out.println(c);
print();
print2();
System.out.println("=====================");
}
}
Object之toString、equals
toString
1、类中重写toString ,将对象以字符串形式输出;没有重写时,调用的是Object的toString,输出的内容是:包名+类名@地址值
==与equals
1、==:比较基本类型的数据值,引用类型的地址值
2、equals:比较基本类型的数据值;引用类型,重写后比较的是对象属性值
public class Person {
public String name;
public String gender;
public int age;
public int num;
public Person() {
}
public Person(String name,String gender,int age,int num) {
this.name=name;
this.gender=gender;
this.age=age;
this.num=num;
}
public String toString() {
return "姓名:"+name+"--性别:"+gender+"--年龄:"+age+"--号码:"+num;
}
public boolean equals(Object obj) {
if(this==obj) {
return true;
}
if(obj instanceof Person) {
return ((Person) obj).name==this.name && ((Person) obj).gender==this.gender && ((Person) obj).age==this.age && ((Person) obj).num==this.num;
}
return false;
}
}