Java面向对象——基础
1. 继承——extends
一个class只能继承一个类,即有且仅有一个父类;但一个父类可以被很多子类继承。
- 父类
Person中的name和age属性不需要在子类Student中重复定义 protected可以将字段或方法的访问权限控制在了继承树内,比private更适合- 这里如果
Person类中的name字段定义的是private,那Student类中的name将会报错
- 这里如果
public class Main {
public static void main(String[] args){
Student stu = new Student();
stu.hello(); //unnamed
}
}
public class Person {
protected String name = "unnamed";
private int age = 0;
}
public class Student extends Person {
public void hello(){
System.out.println(name); //父类Person的name字段,即super.name
}
}
- 向上转型没问题,向下转型时为了避免转型出错,最好通过
A instanceof B来判断是否成功
Person p = new Student();
if (p instanceof Student) {
// 只有判断成功才会向下转型:
Student s = (Student) p; // 一定会成功
}
2. 多态——@override
利用多态,totalTax()只需要和Income的getTax()打交道就行了,完全不需要知道Salary和Grey的存在,也就是说如果要新增/删除一种收入,只需要让它extends Income,然后@override覆写getTax()方法即可。
- Tips:用
final修饰的方法/类/字段,不能被Override。final修饰符有多种作用:final修饰的方法可以阻止被覆写;final修饰的class可以阻止被继承;final修饰的field必须在创建对象时初始化,随后不可修改。
public class Main {
public static void main(String[] args){
Income[] incomes = {
new Income(1000),
new Salary(10000),
new Grey(5000)
};
System.out.println("总纳税:" + totalTax(incomes));
}
public static double totalTax(Income... incomes){
double sumTax = 0.0;
for(Income income:incomes){
sumTax += income.getTax();
}
return sumTax;
}
}
/*
普通收入
*/
class Income{
protected double income;
public Income(double income){
this.income = income;
}
public double getTax(){
return income * 0.1; //普通收入纳10%的税
}
}
/*
工资收入
*/
class Salary extends Income{
public Salary(double income){
super(income);
}
@Override
public double getTax() {
if(income<=5000){ //[0,5000]不纳税
return 0;
}else{ //超出5000的部分纳10%的税
return (income-5000) * 0.1;
}
}
}
/*
灰色收入
*/
class Grey extends Income{
public Grey(double income) {
super(income);
}
@Override
public double getTax() {
return 0;
}
}
总纳税:600.0
3. 抽象类——abstract
抽象类只能用于被继承,其强迫子类实现其抽象方法,并且这个抽象方法必须没有执行代码。
案例:Holiday类如果继承Travel抽象类,那必须要实现buyTickets()这个抽象方法。
public class Main {
public static void main(String[] args){
Holiday holiday = new Holiday();
holiday.buyTickets();
}
}
/*
抽象类 Travel
*/
abstract class Travel{
public abstract void buyTickets(); //抽象方法
}
class Holiday extends Travel{
@Override
public void buyTickets() {
System.out.println("去携程买机票!");
}
}
4. 接口——interface
所谓
interface,就是比抽象类还要抽象的纯抽象接口,因为它不能有实例字段,但是可以有静态字段。
当一个具体的class去实现一个interface时,需要使用implements关键字。
default方法的目的:当给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。(JDK>=1.8)
- Tips:
- 一个类只能
extends一个class;但是可以implements多个interface - 因为接口定义的所有方法默认都是
public abstract的,所以这两个修饰符写不写效果都一样
- 一个类只能
public class Main {
public static void main(String[] args){
Holiday holiday = new Holiday();
holiday.buyTickets();
}
}
/*
接口 Travel
*/
interface Travel{
void buyTickets();
default String passport() { //default方法,可以不覆写
return null;
}
}
class Holiday implements Travel{
@Override
public void buyTickets() {
System.out.println("去携程买机票!");
}
}
5. 静态方法/字段——static
静态字段属于所有实例共享的字段,即:所有实例共享一个静态字段。它是属于class的。
代码中由于number是静态字段,所以将p1.number赋值为10,那么p2.number也自动为10了。
public class Main {
public static void main(String[] args){
Person p1 = new Person("asher",23);
Person p2 = new Person("Chalice",2);
p1.number = 10;
System.out.println(p2.number); //10
}
}
class Person{
private String name;
private int age;
public static int number; //静态字段 number
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
- Tips:上面代码中不推荐用
实例变量.静态字段p1.number去访问静态字段。因为在Java程序中,实例对象并没有静态字段。在代码中,实例对象能访问静态字段只是因为编译器可以根据实例类型自动转换为类名.静态字段来访问静态对象。推荐用类名来访问静态字段。可以把静态字段理解为描述class本身的字段(非实例字段)。对于上面的代码,更好的写法是:
Person.number = 10;
System.out.println(Person.number); //10
接口的静态字段:interface接口虽然不能定义实例字段,但是可以定义静态字段,并且静态字段必须为final类型。实际上因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉:
public interface Person {
int MALE = 1; //等效于 public static final int MALE = 1;
int FEMALE = 2; //等效于 public static final int FEMALE = 2;
}
本文深入解析Java面向对象核心概念,包括继承、多态、抽象类、接口与静态方法的运用,通过具体代码示例展示如何有效利用这些特性增强代码复用性和扩展性。
1800

被折叠的 条评论
为什么被折叠?



