当前位置: 首页 > news >正文

java基础-5 : 面向对象

一.封装

1..构造方法

构造方法是 Java 类中的一个特殊方法,用于在创建对象时初始化对象的成员变量。它的主要特点是:

  1. 方法名必须与类名完全相同(包括大小写)。

  2. 没有返回类型(连 void 也不能写)。

  3. 在 new 对象时自动调用,不能手动调用。

(1) 默认构造方法(无参构造方法)

  • 如果类中没有显式定义任何构造方法,Java 会自动提供一个默认的无参构造方法(内容为空)。

  • 但如果定义了任意构造方法,Java 不再提供默认构造方法,此时如果需要无参构造,必须手动编写。

public class Person {private String name;// 默认构造方法(如果没写任何构造方法,Java会自动生成)public Person() {System.out.println("调用了无参构造方法");}
}

(2) 带参数的构造方法

  • 可以在构造方法中接收参数,用于初始化对象的成员变量。

public class Person {private String name;// 带参数的构造方法public Person(String name) {this.name = name;  // 用 this 区分成员变量和参数}
}

 2.getter/setter

针对私有变量,都要提供对应的getter和setter方法

  • getter:get + 首字母大写的字段名(无参数,返回字段值)

  • setter:set + 首字母大写的字段名(带参数,无返回值)

package test;public class friend {private String name;private int age;public friend(){System.out.println("无参构造方法");}public friend(String name,int age){this.name = name;this.age = age;}//    在成员变量与局部变量中,如果变量名相同,那么局部变量会覆盖成员变量,既就近原则,需要对成员变量使用thispublic void setName(String name){this.name = name;}
//    获取成员变量的值,不需要参数,需要返回值public String getName(){return name;}public void setAge(int a){if(a>=18&&a<30){age = a;}else{System.out.println("年龄不合法");}}public int getAge(){return age;}
}

3.练习1

定义一个things类,私有化成员变量,构造有参,无参方法,设置setter/getter方法

package test;public class things {private int id;private String name;private int price;private int number;public things() {}public things(int id, String name, int price, int number) {this.id = id;this.name = name;this.price = price;this.number = number;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}
}

 定义一个数组,并添加2个things对象

package test;public class test2 {public static void main(String[] args){things[] arr = new things[3];things t1 = new things(1,"apple",10,10);things t2 = new things(2,"banana",20,20);things t3 = new things(3,"orange",30,30);arr[0] = t1;arr[1] = t2;arr[2] = t3;for(int i = 0;i < arr.length;i++){System.out.println(arr[i].getId() + " " + arr[i].getName() + " " + arr[i].getPrice() + " " + arr[i].getNumber());}}
}

 3.练习2

定义一个角色类

package test;import java.util.Random;public class Role {private String name;private int blood;private char gendar;private String face;String[] boyface = {"男1","男2","男3","男4","男5"};String[] girlface = {"女1","女2","女3","女4","女5"};//    构造方法public Role() {System.out.println("无参构造方法");}public Role(String name, int blood,char gendar) {this.name = name;this.blood = blood;this.gendar = gendar;setFace(gendar);}//    getter和setter方法public void setName(String name) {this.name = name;}public String getName() {return name;}public int getBlood() {return blood;}public void setBlood(int blood) {this.blood = blood;}public void setFace(char gendar){Random r = new Random();if(gendar=='男'){int index = r.nextInt(boyface.length);this.face = boyface[index];}else if(gendar=='女'){int index = r.nextInt(girlface.length);this.face = girlface[index];}else{this.face = "人妖";}}public String getFace(){return face;}public void attack(Role role) {Random r = new Random();int hurt = r.nextInt(20) + 1;int remainblood = role.getBlood() - hurt;remainblood = remainblood < 0 ? 0 : remainblood;role.setBlood(remainblood);//      this代表方法调用者System.out.println(this.name + "攻击了" + role.getName() + ",造成了" + hurt+ "点伤害" + role.getName() + "剩余血量为" + remainblood);}
}
package test;public class test {public static void main(String[] args) {Role r1 = new Role("张三",100,'男');Role r2 = new Role("李四",100,'男');while(true){r1.attack(r2);if(r2.getBlood()==0){System.out.println(r2.getName() + "被击杀");break;}r2.attack(r1);if(r1.getBlood()==0){System.out.println(r1.getName() + "被击杀");break;}}}
}

二.继承

  • 单继承:Java类只能直接继承一个父类

  • 传递性:继承关系可以多层传递

  • 构造方法不继承:但子类必须调用父类构造器

  • Object类:所有类的终极父类

  • extends: java使用extends实现单继承

class Animal {public String name;protected int age;private String secret;  // 子类不能直接访问public Animal(){}public Animal(String name, int age) {this.name = name;this.age = age;this.secret = "Animal secret";System.out.println("Animal构造方法被调用");}// 可被子类重写的方法public void makeSound() {hiddenMethod();System.out.println(name + "动物发出了声音");}// private方法 - 对子类不可见private void hiddenMethod() {System.out.println("动物私有方法");}// final方法 - 不能被子类重写public final void breathe() {System.out.println(name + "动物呼吸");}// static方法 - 继承但不重写public static void describe() {System.out.println("类方法");}
}
// 2. 单继承 extends
class Dog extends Animal {// 新增属性private String breed;public Dog(){super();}// 构造方法必须调用父类构造器public Dog(String name, int age, String breed) {super(name, age);  // 必须放在第一行this.breed = breed;System.out.println("Dog构造方法被调用");}// 方法重写(Override)@Overridepublic void makeSound() {System.out.println(name + "狗叫");}// 新增方法public void fetch() {System.out.println(name + " is fetching");}// 尝试重写static方法 - 实际上是隐藏(hiding)而非重写public static void describe() {System.out.println("This is a Dog class");}// 重写toString,使用super调用父类方法@Overridepublic String toString() {return super.toString() + "[breed=" + breed + "]";}
}
// 3. 多层继承
class Puppy extends Dog {public Puppy(String name, int age, String breed) {super(name, age, breed);System.out.println("Puppy构造方法被调用");}@Overridepublic void makeSound() {System.out.println(name + " yelps: Yip yip!");}
}

1.构造方法

  • 子类构造器必须调用父类构造器

  • 如果子类构造器没有显式调用:

  1. 默认调用父类无参构造器super()
  2. 如果父类没有无参构造器,编译报错

2.方法重写

  • 子类重新定义父类已有的方法

  • 必须遵守"两同两小一大"规则:

  1. 两同:方法名相同、参数列表相同
  2. 两小:返回值类型相同或是子类、抛出的异常相同或是子类
  3. 一大:访问权限相同或更大

3.super关键字

  • 访问父类的成员变量:super.variable

  • 调用父类的方法:super.method()

  • 调用父类构造器:super(...)(必须放在子类构造器第一行)

public class test3 {public static void main(String[] args) {zi z = new zi();z.print();z.move();}
}
class fu{String name = "123";public void eat(){System.out.println("fu eat");}public void sleep(){System.out.println("fu sleep");}
}
class zi extends fu{String name = "456";public void print(){String name = "789";System.out.println(name);System.out.println(this.name);System.out.println(super.name);}public void move(){this.eat();super.eat();}@Overridepublic void eat(){System.out.println("zi eat");}@Overridepublic void sleep(){System.out.println("zi sleep");}
}
789
456
123
zi eat
fu eat

4.final关键字与继承

  • final class:禁止被继承(如String类)

  • final method:禁止被子类重写

  • final variable:常量,不可修改

5.抽象类与继承

  • 抽象类(abstract class)必须被

    继承才能使用

  • 可以包含抽象方法(只有声明没有实现)

  • 子类必须实现所有抽象方法,除非子类也是抽象类

// 1. 抽象类和抽象方法
abstract class Shape {protected String color;public Shape(String color) {this.color = color;}// 抽象方法 - 必须被子类实现public abstract double area();// 具体方法public String getColor() {return color;}
}
// 实现抽象类
class Circle extends Shape {private double radius;public Circle(String color, double radius) {super(color);this.radius = radius;}@Overridepublic double area() {return Math.PI * radius * radius;}// 重写Object的equals方法@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (!(obj instanceof Circle)) return false;Circle other = (Circle) obj;return Double.compare(radius, other.radius) == 0&& color.equals(other.color);}
}

1.在继承中构造方法不会被继承因为,构造方法的方法名和类名相同,当一个类中没有构造方法时,会默认生成一个无参构造方法,
2.成员变量可以被继承,私有(private)或非私有(如public)不过private需要通过getter和setter方法来访问
虚方法表:1.非private,非static,非final的方法
3.成员方法:虚方法表可以,否则不行

三.多态

  • 继承关系:存在父子类关系

  • 方法重写:子类重写父类方法

  • 向上转型:父类引用指向子类对象

1.调用成员变量:编译看左边,运行看左边

  1. 编译看左边,左边是Animal,Animal中没有name属性,则编译报错
  2. 运行看左边:java在运行时,实际获取的是左侧

2.调用成员方法:编译看左边,运行看右边

  1. 因为成员方法中,子类重写了会把虚方法表里的内容覆盖
  2. 多态的弊端: 不能调用子类的特有方法,因为编译看左侧,左侧没有,所以报错
  3. 解决方案:进行强制转换
public class Person {private String name;private int age;public Person(){}public Person(String name, int age) {this.name = name;this.age = 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;}public void show(){System.out.println("我叫"+name+",年龄"+age);}
}
//子类1
public class Student extends Person{@Overridepublic void show(){System.out.println("我是学生:"+getName()+"年龄:"+getAge());}
}
//子类2
public class Admin extends Person{@Overridepublic void show(){System.out.println("我是管理员:"+getName()+"年龄:"+getAge());}
}
//子类3
public class Teacher extends Person{@Overridepublic void show(){System.out.println("我是老师:"+getName()+"年龄:"+getAge());}
}
public class 多态 {public static void main(String[] args) {Person p1 = new Admin();Person p2 = new Student();Person p3 = new Teacher();
//        方法一:
//        先判断是否为Dog类型,如果是,则进行强制转换,转变变量名为d1
//        如果不是,则不进行强制转换,结果直接为falseif(p1 instanceof Admin a){a.setName("admin");a.show();}if(p2 instanceof Student s){s.setName("student");s.show();}
//        方法二:直接使用强转if(p3 instanceof Teacher){Teacher t1 = (Teacher) p3;t1.show();}}public static void register(Person p){p.show();}
}
我是管理员:admin年龄:0
我是学生:student年龄:0
我是老师:null年龄:0

http://www.dtcms.com/a/286908.html

相关文章:

  • python网络爬虫(第三章/共三章:驱动浏览器窗口界面,网页元素定位,模拟用户交互(输入操作、点击操作、文件上传),浏览器窗口切换,循环爬取存储)
  • RPG60.生成可拾取物品
  • 拓扑排序/
  • 安卓Android项目 报错:系统找不到指定文件
  • Python编程:从入门到实践
  • rpa机器人流程自动化软件公司是做什么的?如何选择RPA厂商?简要介绍RPA技术、应用场景和未来趋势
  • Shell变量操作
  • Linux内核设计与实现 - 第4章 进程的调度
  • 函数返回值问题,以及返回值的使用问题(c/c++)
  • [FDBUS4.2] watcher的使用
  • STM32-CAN
  • vs openssl编译提示无法打开文件“libssl.lib”或“libcrypto.lib”
  • 理解 VMA 与 LMA
  • 【实战】Dify从0到100进阶--文档解读(8)文档列表节点
  • 深入剖析 Delta Live Tables (DLT):声明式数据管道的核心原理与底层实现
  • git:tag标签远程管理
  • 公贝固定资产管理系统对接HR、财务及采购系统的方案与效益
  • 【实用工具】HDCleaner:高效、安全、免费的系统清洁工具,免费的电脑清理垃圾神器,20秒扫出20G垃圾!
  • LP-MSPM0G3507学习--05中断及管脚中断
  • 习题4.1 输出3个人的顺序
  • APIs案例及知识点串讲(下)
  • NFS读写性能评估与优化指南(上)
  • Android性能优化之电量优化
  • C 语言字符大小写互转:tolower / toupper 详解与实战
  • MySQL使用any_value()函数解决only_full_group_by报错
  • IT 和OT指的什么?
  • 短视频矩阵的时代结束了吗?
  • 智能点餐推荐网站,解决选择困难
  • Linux基础IO通关秘籍:从文件描述符到重定向
  • 使用wrk对api接口进行性能测试