访问修饰符,快捷键使用
// 冒泡排序
/*
1.源码文件都写在src目录下
2.编译后会生成out文件夹, 存放 .class 可执行文件, 每个类对应一个
3.包相当于一个文件夹, 便于管理源码, 包外文件可以导入包调用包里的类
4.程序开头的 package 用来声明当前类所在的包
#快捷键使用#
1. alt + / 补全代码
2. ctrl + shift + L 自动对其代码
3. shift +F10 快速运行代码
4. Ctrl + h 看类的继承关系
5. Ctrl + b 快速定位方法位置
6. new 类型.var 自动生成变量名
#常用模板#
1. sout 快速打印输出语句
2. main 主函数
3. fori 以i为变量的for循环
#访问修饰符#
1.public 对外公开
2.protected 对子类和同一个包的类公开
3.无修饰符, 对同一个包的类公开
4.private 只有类本身可以访问
* */
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] A = {8, 7, 10, 5, 1, 3, 15};
// 自己编写方法进行排序
maopao(A);
int[] B = {10, 7, 16, 5, 8, 3, 22};
// 通过Arrays包中的sort方法排序
Arrays.sort(B);
System.out.print("排序后数组为:");
for(int i = 0; i < A.length; i++){
System.out.print(A[i] + " ");
}
System.out.println();
for(int i = 0; i < B.length; i++){
System.out.print(B[i] + " ");
}
System.out.println();
}
// 编写冒泡排序的方法
static void maopao(int[] A){
for(int i = 0; i < A.length; i++){
for(int j = i + 1; j < A.length; j++){
if(A[i] > A[j]){
int f = A[i];
A[i] = A[j];
A[j] = f;
}
}
}
return ;
}
}
面向对象三大特征
封装
// 封装
/*
定义:封装指把抽象的属性和方法封装在一起, 数据被保护在内部, 通过背授权
的方法对数据进行操作
#实现步骤#
1.把属性进行私有化 private
2.提供 public set方法, 对属性判断并赋值
3.提供一个 public get 方法, 获取属性的值
4.若使用构造方法, 则可以在构造方法中调用 set 方法
* */
public class FengZhuang {
public static void main(String[] args) {
Person person = new Person();
// 调用 set 给属性赋值
person.setName("神里绫华");
person.setAge(18);
person.setSalary(520521);
System.out.println(person.info());
// 使用构造器调用 set 方法
Person person1 = new Person("宵宫", 101, 1314);
System.out.println(person1.info());
}
}
class Person{
public String name;
// 年龄和工资私有化
private int age;
private double salary;
public String info(){
return "姓名 " + this.name + " 年龄 " + this.age
+ " 工资 " + this.salary;
}
public Person(String name, int age, double salary){
// 在构造方法中调用 set 方法判断是否合法
setName(name);
setAge(age);
setSalary(salary);
}
public Person(){
}
// 右键生成get 和 set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
// 对年龄进行判断
if(age >=1 && age <= 100){
this.age = age;
}
else{
System.out.println("年龄不符合规定");
// 给个默认的年龄
this.age = 22;
}
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
继承
// 类的继承
/*
使用: 定义子类时在后面添加 extends + 父类
要点:
1.子类继承父类所有属性和方法, 非私有属性和方法在子类里可直接访问,
私有属性通过父类公共方法去访问
2.当创建子类对象时, 默认先调用父类的无参构造器, 若父类中已经重写
构造器, 则在每个子类构造器中都要用 super(父类构造器参数)指定构造器
3.子类构造器调用某个父类构造器, 使用 super(参数), 且必须写在第一行,
且 super 只能在构造器中使用, 不能和 this() 共存
4.java中所有类都是Object类的子类, 父类构造器调用要追溯到 Object 类
5.一个类只能继承一个类, 若需要继承多个类, 则通过父类继承另一个类达成
6.若一个类包括其父类有同一个属性, 则调用时采取就近原则, 自己->爹->爷
* */
package JiCheng;
public class Test {
// 定义四个不同访问权限的值
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
public Test(){
System.out.println("调用无参父类构造器");
}
public Test(int a1, int a2){
System.out.println("调用有参父类构造器");
}
// 子类通过 get 访问私有属性 n4
public int getN4() {
return n4;
}
}
// 子类
/*
#super使用#
(在同名时区分父类与子类)
1.访问父类的属性 super.属性名
2.访问父类的方法 super.方法名(参数)
3.访问父类构造器 super(参数),和访问本类构造器 this(参数) (第一句且只能有一个)
* */
package JiCheng;
public class Son1 extends Test{ // 继承父类Test
public Son1(){
System.out.println("调用son1无参构造器");
}
public Son1(int a1, int a2){
// 使用 super 指定需要调用的父类构造器
super(a1, a2);
System.out.println("调用son1有参构造器");
}
// 访问父类的属性
public void prt(){
System.out.println("父类属性:" + "n1=" + n1 +
" n2=" + n2 + " n3=" + n3);
System.out.println(" n4=" + getN4());
}
}
继承中方法的重写
public class Animal {
String name = "动物";
int age = 10;
public void sleep(){
System.out.println("睡觉觉");
}
public void run(){
System.out.println("跑步步");
}
public void eat(){
System.out.println("吃饭饭");
}
public void show(){
System.out.println("你好呀");
}
}
public class Cat extends Animal{
public void eat(){
System.out.println("小猫吃鱼");
}
public void catchMouth(){
System.out.println("猫爪老鼠");
}
}
多态
对象的上下转型
/* 多态
1.对象编译类型和运行类型可能不一致, 创建对象时可以指向其的子类
#向上转型#
2.语法: 父类类型 引用名 = new 子类类型,
等号左边是编译类型, 右边运行类型(可变)
编译时认为是Animal, 运行时是Dog
3.该animal对象可以调用父类所有成员, 但不能调用子类特有的成员, 调用方法时
从子类向上查找
#向下转型#
4.语法:子类类型 引用名 = (子类类型) 父类引用,
只能强转父类的引用, 不能强转父类的对象
父类引用必须是指向当前目标类型的对象
向下转型之后可以调用子类中所有成员
* */
package DuoTai;
public class Mainc {
public static void main(String[] args) {
// 向上转型, 父类的引用指向子类的对象
// animal 可以调用父类所有属性方法, 但不能调用子类特有的成员
Animal animal = new Cat();
animal.sleep();
animal.eat(); // 向上转型:方法看子类(运行), 属性看父类(编译)
animal.show(); // 子类没有则看父类
// 向下转型
Cat cat = (Cat) animal;
// 把 Animal 强转为 Cat 对象, 可调用Cat的特有方法
cat.catchMouth();
}
}
举例
// 父类
public class Employee {
public String name;
public double salary;
public double getAnnual(){
return salary * 12;
}
}
// 经理类
public class JingLi extends Employee{
public double bonus;
public JingLi(String n, double s, double b){
this.name = n;
this.salary = s;
this.bonus = b;
}
public void manage(){
System.out.println("经历管理员工中");
}
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
}
// 普通员工类
public class PuGong extends Employee{
public PuGong(String n, double s){
this.name = n;
this.salary = s;
}
public void work(){
System.out.println("员工工作中");
}
@Override
public double getAnnual() {
return super.getAnnual();
}
}
// 主方法
public class mainc {
public static void main(String[] args) {
// 向上转型
Employee e1 = new PuGong("jack", 2000);
Employee e2 = new JingLi("mary", 3000, 1000);
mainc m = new mainc();
m.showAnnual(e1);
m.showAnnual(e2);
m.showWork(e1);
m.showWork(e2);
}
// 获取每个员工的工作状态
public void showWork(Employee e){
if(e instanceof PuGong){
PuGong p = (PuGong) e;
p.work();
}
else if(e instanceof JingLi){
JingLi j = (JingLi) e;
j.manage();
}
else {
System.out.println("类型错误");
return ;
}
}
}
动态绑定机制
/*
动态绑定
1.当调用对象方法时, 该方法会和该对象的内存地址(运行类型)绑定
只要调用方法都从运行类型开始找, 即使父类中调用父类和子类都有的方法
2.当调用对象属性时, 没有动态绑定机制, 哪里声明哪里用
* */
package DuoTai;
public class DongTaiBangDing {
public static void main(String[] args) {
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
}
}
class A{
public int i =10;
public int sum(){
// 子类中没有 sum 方法, 固调用父类中的, 又调用getI方法先从子类中找
return getI() + 10;
}
public int sum1(){
return i + 10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i = 20;
// 父类调用 getI 优先找运行类型, i是属性, 采取就近原则
public int getI() {
return i;
}
}
Object 方法重写
// # ==和equals(重写) #
/*
使用 Ctrl+B 查看源码, 或右键-> 转到(go to)-> 声明
1. == 若判断基本类型, 判断的是值是否相等
2. == 若判定引用类型, 判断地址是否相等, 即是不是一个对象
* */
package DuoTai;
import java.util.Objects;
public class Equals {
public static void main(String[] args) {
// equals 是Object类中的方法, 只能判断引用类型地址是否相等
// 其子类对 equals 方法重写, 判断数据是否相等, 下为 String 类重写
"a".equals("b");
Integer integer = new Integer(1000);
Integer integer1 = new Integer(1000);
System.out.println(integer == integer1); // 判断地址
System.out.println(integer.equals(integer1)); // 判断值是否相等
// equals 方法的重写, 判断两个person类是否相等
Person person1 = new Person("jack", 18, "男");
Person person2 = new Person("Mary", 18, "女");
System.out.println(person1.equals(person2));
// toString 重写, 该方法在Object 中返回 全类名+@+十六进制哈希值
System.out.println("toString 结果:" + person1.toString());
// 重写前 :DuoTai.Person@ba6817e3
// 重写后: 一般是输出属性值
}
}
class Person{
String name;
int age;
String sex;
public Person(String name, int age, String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
// 对 equals 方法进行重写
@Override
public boolean equals(Object o) { // 传进的类为 Object!
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
// getClass() 获取对象的类型
Person person = (Person) o; // 向下转型
return age == person.age && Objects.equals(name, person.name) && Objects.equals(sex, person.sex);
}
// 两个引用指向同一个对象 哈希值相同, 不指向一个对象则不同
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
// 重写后: 一般是输出属性值, 在输出对象时默认调用该方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}