文章目录
一、类
package com.atguigu.contact;
public class MyPacakage {
public static void main(String[] args) {
//声明类
Turtle turtle=new Turtle();
turtle.color="绿色";
System.out.println(turtle.color);
turtle.climb("大黄");
}
}
//创建一个类
class Turtle{
//类的属性
String color;
int legs=4;
//类的方法
void climb(String name){
System.out.println("我是乌龟"+name);
}
}
二、内存解析
三、成员变量+局部变量
三、方法的声明
package com.atguigu.contact;
import java.util.Arrays;
public class MyPacakage {
public static void main(String[] args) {
Student[] s = new Student[20];
for (int i = 0; i < 20; i++) {
s[i] = new Student();
s[i].number = i + 1;
s[i].state = (int) (Math.random() * 5 + 1);
s[i].score = (int) (Math.random() * 101 + 1);
}
MyPacakage test = new MyPacakage();
// 打印state為3
test.display_3(s);
//冒泡排序
test.bubble(s);
// 遍历
test.allThrough(s);
}
public void allThrough(Student[] s) {
for (int i = 0; i < s.length; i++) {
s[i].display(s[i]);
}
}
public void display_3(Student[] s) {
for (int i = 0; i < s.length; i++) {
if (s[i].score == 3) {
s[i].display(s[i]);
}
}
}
public void bubble(Student[] s) {
// 冒泡排序來遍歷成績
for (int j = 0; j < s.length - 1; j++) {
for (int i = 1; i < s.length - j; i++) {
if (s[i - 1].score > s[i].score) {
Student temp = s[i];
s[i] = s[i - 1];
s[i - 1] = temp;
}}}}
}
class Student {
int number;
int state;
int score;
public void display(Student s) {
System.out.println("學號:" + s.number + "年級:" + s.state + "成績:" + s.score);
}
}
匿名对象
方法的重载
类中具有两个或两个以上的相同方法名,但形参列表不同就构成了方法重载。
可变形参
数据类型…变量名
方法参数的值传递机制
-
如果是基本数据类型,参数传递时传递的是变量的值
-
引用数据类型,参数传递时传递的是地址值
-
方法调用时,实际传递给形参的数据,叫实参
-
方法定义时,方法小括号里的参数,叫做形参
-
如果是基本数据类型,实参传递给形参时,只是单纯的变量值传递。
-
如果是引用数据类型,实参传递给形参时,传递的是地址值。
参数类型为基本数据类型
调用方法交换m,n会发现main函数中的m,n位置并没交换,究其本质,看它的内存传递机制。
== 参数类型为引用数据类型==
调用方法交换m,n会发现main函数中的m,n位置也交换了,究其本质,看它的内存传递机制。
递归
package Array_ex;
public class diGui {
public static void main(String[] args) {
diGui test = new diGui();
System.out.println(test.f(10));
}
//递归,f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n);其中n是>0,求f(10)
public int f(int n) {
if(n==0) {
return 1;
}else if(n==1) {
return 4;
}else {
return 2*f(n-1)+f(n-2);
}
}
}
四、封装
package com.atguigu.contact;
public class MyPacakage {
public static void main(String[] args) {
Turtle turtle=new Turtle();
turtle.setLegs(4);
System.out.println(turtle.getLegs());
}
}
//创建一个类
class Turtle{
//将属性设置为私有属性
private int legs;
//设置私有属性的值
public void setLegs(int nums) {
if(0<nums && nums%2==0) {
legs=nums;
}else {
legs=0;
}
}
//获取私有属性
public int getLegs() {
return legs;
}
void climb(String name){
System.out.println("我是乌龟"+name);
}
}
Java的四种权限修饰符
五、类的构造器(Constructor)
- 作用:1)用来创建对象 new+构造器;2)初始化对象的属性信息。
- 若没有显示定义的构造器,系统默认提供一个空参的构造器。
- 若显示定义了类的构造器,则系统不再提供默认的空参构造器
- 一个类中至少有一个构造器
- 定义构造器的格式:修饰符 类名(形参列表){}
== 构造器很像python里的__init__,用于对象的属性初始化赋值操作 ==
package com.atguigu.concat;
public class MyObject {
public static void main(String[] args) {
Person p=new Person(18,"Tom");
System.out.println(p.age+p.name);
}
}
class Person{
int age;
String name;
public Person(int n,String m) {
age=n;
name=m;
}
}
补充:属性赋值操作的先后顺序
补充:JavaBean
补充:UML类图
this关键字
类比python的self.
练习:银行收存款余额
package Array_ex;
public class Account {
private double balance;
public Account(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
// 存款
public void deposit(double amt) {
if (amt > 0) {
balance += amt;
System.out.println("存钱成功");
}
}
// 取款
public void withdraw(double amt) {
if (balance >= amt) {
balance -= amt;
System.out.println("取钱成功");
return;
}
System.out.println("余额不足,取款失败");
}
}
package Array_ex;
public class Customer {
private String firstName;
private String lastName;
private Account account;
public Customer(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
package Array_ex;
public class Bank {
private Customer[] customers;//存放多個客戶的數組
private int numberOfCustomer;//記録客戶的個數
public Bank() {
customers = new Customer[10];
}
public void addCustomer(String f, String l) {
Customer c = new Customer(f, l);
customers[numberOfCustomer++]=c;
}
public int getNumberOfCustomer() {
return numberOfCustomer;
}
public Customer getCustomers(int index) {
return customers[index];
}
}
package Array_ex;
public class BankTest {
public static void main(String[] args) {
Bank b = new Bank();
b.addCustomer("Jane","Smith");
b.getCustomers(0).setAccount(new Account(110.0));
b.getCustomers(0).getAccount().deposit(10.0);
b.getCustomers(0).getAccount().withdraw(10.0);
}
}
pacakge关键字
MVC设计模式
import关键字
六、继承(extends)
package com.atguigu.contact;
// 父类
public class Person {
int legs = 2;
int eyes = 2;
public Person() {
}
public void eat() {
System.out.println("吃飯");
}
}
//子类
package com.atguigu.contact;
public class Student extends Person {
int age = 18;
public Student() {
}
public void study() {
System.out.println("學習");
}
}
//主函数
package com.atguigu.contact;
public class MyTest {
public static void main(String[] args) {
Person p = new Person();
Student s = new Student();
p.eat();
s.eat();
s.study();
}
}
方法的重写
注意:重写方法非static,非private
方法的重载和重写
super关键字
//父类
package myex;
public class Account {
private int id;
private double balance;
private double annualInterestRate;
public Account() {
}
public Account(int id, double balance, double annualInterestRate) {
super();
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public double getBalance() {
return balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setId(int id) {
this.id = id;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
public double getMonthlyInterest() {
return getAnnualInterestRate()/12;
}
public void withdraw(double amount) {
if (amount>balance) {
System.out.println("余额不足,取款失败");
}else {
balance-=amount;
// System.out.println("取款成功,余额为:"+balance);
}
}
public void deposit(double amount) {
balance+=amount;
// System.out.println("存款成功,余额为:"+balance);
}
}
//子类,练习super关键字
package myex;
public class CheckAccount extends Account {
double overdraft;
public CheckAccount(int id, double balance, double annualInterestRate, double overdraft) {
super(id, balance, annualInterestRate);
this.overdraft = overdraft;
}
public void withdraw(double amount) {
if (amount<getBalance()) {
System.out.println("可以直接取款");
//setBalance(getBalance()-amount);
super.withdraw(amount);
}else {
double needOverdraft = amount-getBalance();
if(needOverdraft>overdraft) {
System.out.println("用户超过可透支额的限额");
}else {
overdraft-=needOverdraft;
setBalance(0.0);
}
}
}
}
//测试用例
package myex;
public class AccountTest {
public static void main(String[] args) {
CheckAccount c = new CheckAccount(1122,20000,0.0045,5000);
c.withdraw(5000);
System.out.println("余额为:"+c.getBalance());
System.out.println("允许透支余额为:"+c.overdraft);
c.withdraw(18000);
System.out.println("余额为:"+c.getBalance());
System.out.println("允许透支余额为:"+c.overdraft);
c.withdraw(3000);
System.out.println("余额为:"+c.getBalance());
System.out.println("允许透支余额为:"+c.overdraft);
}
}
子类对象实例化的全过程
七、多态
package com.atguigu.concat;
//父类
public class Person1 {
int age;
String neme;
public void eat() {
System.out.println("人吃饭");
}
}
//子类
public class Man extends Person1 {
public void eat() {
System.out.println("男的吃饭多");
}
}
//测试用例
public class myex {
public static void main(String[] args) {
Person1 p = new Person1();//多态性
Person1 p2 = new Man();
p2.eat();
}
}
类的向下转型
向下转型:将父类强转成子类
package com.atguigu.concat;
public class myex {
public static void main(String[] args) {
Person1 p2 = new Man();
Man m = (Man)p2;//强制类型转换
m.isSmoking=false;
p2.eat();
}
}
instanceof关键字
八、Object类
equals()
Object类中判断两个对象的地址是否相同,但我们使用时的目的往往是判断对象的内容是否相同,因此要对对象进行重写。
==和equals()有什么区别?
重写equals方法
package com.atguigu.contact;
public class Person {
String name;
int age;
int id=1;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
@Override
//重写原则,比较两个对象实体内容是否相同
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if (obj instanceof Person) {
Person objTest = (Person)obj;
//比较对象的每个属性是否都相同
return this.age == objTest.age && this.name.equals(objTest.name);
}
return false;
}
}
//测试用例
package com.atguigu.contact;
public class MyTest {
public static void main(String[] args) {
Person p1 = new Person("张三", 18);
Person p2 = new Person("张三", 18);
System.out.println(p1.equals(p2));
}
}
toString()
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
}
- getClass()、hashCode()、clone()、 finalize()、wait()、notify()、notifyAll()
Junit单元测试
import org.junit.jupiter.api.Test;
public class JunitTest {
int num = 10;
@Test
public void testEquals() {
String s1="MM";
String s2="MM";
System.out.println(s1.equals(s2));
System.out.println(num);
}
}
包装类
基本类、包装类和String类的转换
package com.atguigu.contact;
import org.junit.jupiter.api.Test;
public class WrapperTest {
// 基本数据类型--->包装类:调用包装类xxx.valueOf(基本数据类型)
// 应用场景:比如形参传入的对象要求是类对象,则需把基本数据类型转换为包装类
@Test
public void test1() {
// 方法一:包装类 = xxx.valueOf(基本数据类型)
int num1 = 10;
Integer in2 = Integer.valueOf("123");
Integer obj = Integer.valueOf(num1);// jdk1.9之后官方推荐
Boolean b1 = Boolean.valueOf("true123");// false
// 方法二、自动装箱
int i1 = 1;
Integer ii1 = i1;
}
// 包装类--->基本数据类型:调用包装类的 对象.xxxValue()
// 应用场景:包装类无法做加减乘除,我们就需要转换为基本数据类型
@Test
public void test2() {
// 方法一:基本数据类型=对象.xxxValue()
Integer in1 = Integer.valueOf("123");
int i1 = in1.intValue();
// 方法二:自动拆箱
Integer ii1 = 1;
int i3 = ii1;
}
// 包装类、基本数据类型--->String
@Test
public void test4() {
// 方法一:连接运算
int num1 = 10;
String str1 = num1 + "";
// 调用ValueOf()
String str2 = String.valueOf(num1);
}
// String--->包装类、基本数据类型:调用包装类的parseXxx()
@Test
public void test5() {
String str1 = "123";
int num2 = Integer.parseInt(str1);
}
}
应用示例
package myex4;
import java.util.Scanner;
public class VectorTest {
public static void main(String[] args) {
Vector v = new Vector();
for(int i=0;i<4;i++) {
System.out.println("请输入学生成绩:");
Scanner score = new Scanner(System.in);
Object s = score.nextInt();
v.addElement(s);
}
System.out.println("插入元素结束");
Object obj = v.elementAt(0);
System.out.println(obj);
int a = (int) obj;
System.out.println(v.scoreGrade(a));
}
}
class Vector{
int[] score = new int[5];
int total = 0;
public void addElement(Object obj) {
score[total++]=(int) obj;
}
public Object elementAt(int index) {
Object obj = score[index];
return obj;
}
public int size() {
return total;
}
public char scoreGrade(int s) {
int max=score[0];
for(int i=1;i<total;i++) {
if(score[i-1]<score[i]) {
max = score[i];
}
}
if (max-s<10) {
return 'A';
}else if(max-s<20) {
return 'B';
}else if(max-s<30) {
return 'C';
}else {
return 'D';
}
}
}
Static关键字
static 修饰属性
注意static常和final搭配使用
package myex4;
public class StaticTest {
public static void main(String[] args) {
Chinese c1 = new Chinese();
c1.name="张三";
c1.age=12;
Chinese c2 = new Chinese();
c2.name="张一";
c2.age=13;
c2.nation="China";
System.out.println(c1.nation);
System.out.println(Chinese.nation);
}
}
class Chinese{
String name;
int age;
static String nation;
}
类变量和实例变量内存解析
static修饰方法
package com.atguigu.contact;
import org.junit.jupiter.api.Test;
public class WrapperTest {
@Test
public void test1() {
Person1.show();
Person1 p = new Person1();
p.eat();
}
}
class Person1{
int age;
String name;
public void eat() {
System.out.println("人吃饭。");
show();
}
public static void show() {
System.out.println("人走路。");
//eat();
}
}
单例设计模式
- 饿汉式设计模式
package com.atguigu.p2.bean;
/*
單例設計模式
1、所谓单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
*/
public class SigletonTest1 {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1==bank2);//true
}
}
//饿汉式(上来就New一个对象)
class Bank{
//私有化类的构造器
private Bank() {
}
//内部创建类的对象
//要求此对象必须声明为静态的
private static Bank instance = new Bank();
//提供公共静态方法,返回类的对象
public static Bank getInstance() {
return instance;
}
}
- 懒汉式(啥时用对象,啥时造对象)
package com.atguigu.p2.bean;
/*
單例設計模式
1、所谓单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
*/
public class SigletonTest1 {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1==bank2);//true
}
}
//懒汉式
class Bank{
//私有化类的构造器
private Bank() {
}
//声明当前类对象,没有初始化
//此对象声明为static
private static Bank instance = null;
//声明public、static的返回当前类对象的方法
public static Bank getInstance() {
if (instance == null) {
instance = new Bank();
}
return instance;
}
}
- 饿汉式和懒汉式的区别
- 单例模式优点
- 单例模式具体应用场景
Main方法怎么在运行时传入数据
package myex4;
public class StaticTest {
public static void main(String[] args) {
for(int i=0;i<args.length;i++) {
System.out.println("*****"+args[i]);
int num2 = Integer.parseInt(args[i]);
System.out.println("^^^^^"+args[i]);
}
}
}
首先编译,生成字节码文件
选择Run As -->Run Configurations
代码块
final关键字
-
final修饰类
-修饰变量和方法
-
- final修饰属性
显示初始化、代码块中赋值、构造器中初始化(若构造器有n个,则每个构造器都要给常量赋值),不能使用默认初始化
- final修饰属性
-
package com.atguigu.p2.bean;
class Bank {
// final修饰属性
//1、显式初始化
final int ACCOUNT = 10;
final int LEFT;// 常量
final int RIGHT;
// 2、代码块赋值
{
LEFT = 1;
}
// 3、构造器中初始化,所有構造器中都要初始化
public Bank() {
RIGHT = 2;
}
public Bank(int n) {
RIGHT = n;
}
}
-
- 修饰局部变量
//final修饰方法体里的局部变量
class A{
public void show() {
final int NUM = 10;
}
public void show(final int num) {
//意义是在方法体内不可以对形参进行修改,只可以调用。
//例如num++是不对的,它对num进行了修改
final int NUM = num;
}
}
抽象类和抽象方法
package Array_ex;
public class AbstractTest {
//一旦person类抽象,不可实例化
// Person p1 = new Person();
// p1.eat();
}
abstract class Person{
String name;
int age;
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("人吃饭");
}
//抽象方法,没有方法体
public abstract void walk();
}
class Student extends Person{
//子类调用父类构造器
public Student(String name,int age) {
super(name,age);
}
public void walk() {
System.out.println("我重写一下抽象方法");
}
}
抽象在开发中的必要性
- 开发中可以提示你对子类方法进行重写
abstract使用的注意点
抽象类和多态,自己领悟
匿名子类
public class AbstractTest {
//匿名对象
// new Student().walk();
//创建一个匿名子类的对象
Person p = new Person() {
@Override
public void walk() {
}
};
}
抽象应用:模版方法设计模式
package Array_ex;
import java.util.Arrays;
/*
* 模版方法设计模式
*/
public class TemplateTest {
public static void main(String[] args) {
MyCode m = new MyCode();
m.spendTime();
}
}
abstract class Template {
// 测试一段代码的运行时间
public void spendTime() {
long start = System.currentTimeMillis();
this.code();
long end = System.currentTimeMillis();
System.out.println("程序运行时间:" + (end - start));
}
public abstract void code();
}
class MyCode extends Template {
@Override
public void code() {
int[] arr = new int[] { 1, 4, 3, 2, 9 };
for (int j = 0; j < arr.length; j++) {
for (int i = 1; i < arr.length-j; i++) {
if (arr[i] > arr[i - 1]) {
int temp = arr[i];
arr[i] = arr[i - 1];
arr[i - 1] = temp;
}
}
}
System.out.println("排序后的数组:" + Arrays.toString(arr));
}
}
接口
- 示例
package Array_ex;
public class InterfaceTest {
public static void main(String[] args) {
Plane p = new Plane();
p.fly();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900;
int MIN_SPEED = 1;//书写时可以省略public static final
//抽象方法
public abstract void fly();
void stop();//省略了public abstract
}
interface Attack{
void attack();
}
class Plane implements Flyable,Attack{
@Override
public void fly() {
System.out.println("起飞");
}
@Override
public void stop() {
System.out.println("停止");
}
@Override
public void attack() {
System.out.println("打你");
}
}
接口应用示例
//USB接口示例
/*体现了多态,匿名接口等*/
package Array_ex;
public class USBTest {
public static void main(String[] args) {
//非匿名接口的匿名对象
run(new UDisk());
//匿名接口的匿名对象
run(new USB() {
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void end() {
System.out.println("手机停止工作");
}});
}
//多态
public static void run(USB u) {
u.start();
u.end();
}
}
interface USB{
void start();
void end();
}
class UDisk implements USB{
@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void end() {
System.out.println("U盘结束工作");
}
}
class Mp3 implements USB{
@Override
public void start() {
System.out.println("MP3开始工作");
}
@Override
public void end() {
System.out.println("MP3结束工作");
}
}
代理模式
package Array_ex;
//import sun.nio.ch.Net;
public class NetworkTest {
public static void main(String[] args) {
Server s = new Server();
ProxyServer p = new ProxyServer(s);
p.browse();
}
}
interface NetWork{
public void browse();
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work) {
this.work = work;
}
public void check() {
System.out.println("联网前检查工作");
}
@Override
public void browse() {
work.browse();
}
}
工厂模式
了解即可
- 接口中定义的静态方法只能接口自己调用。
- 可以通过实现类的对象来调用接口的默认方法。
- 若实现类重写了接口默认方法,则调用时调用的是重写方法。
- 若子类(实现类)继承的父类和实现的接口中有同名同参数方法,若子类(实现类)没有重写该方法,则调用的是父类方法。
- 实现类实现了多个接口,这些接口具有同名同参数方法,则调用该方法时会报错。
内部类
public class Inner {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类)
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(静态的成员内部类)
Person p = new Person();
Person.Bird b = p.new Bird();
}
}
class Person{
String name;
public void eat() {
System.out.println("人吃饭");
}
//静态成员内部类
static class Dog{
String name;
public void show() {
System.out.println("狗");
}
}
//非静态成员内部类
final class Bird{
String name;
public Bird() {
Person.this.eat();
}
}
public void method() {
//局部内部类
class AA{
}
}
}