面向对象(高级篇)
1. 关键字:static
静态变量,所有的类可以共享该变量
-
static:静态的
-
用来修饰结构:属性、方法、代码块、内部类
-
static修饰属性:
- 成员变量:
- 按照是否使用static修饰:
- 使用static修饰的:静态变量、类变量(属性)
- jdk6及以前存放在方法区、jdk7以后存放在堆内存
- 所有对象共享一份
- 随着类的加载而加载(由于类只会加载一次,所以只存在一份静态变量)
- 可以直接使用类调用、也可以使用对象调用
- 随着
类
的卸载而消亡
- 不使用static修饰的:非静态的变量、实例变量
- 随着对象的创建而创建
- 只能使用
对象
调用 - 随着
对象
的消亡而消亡
- 使用static修饰的:静态变量、类变量(属性)
- 按照是否使用static修饰:
- 局部变量:
- 方法内、方法的形参、构造器内、构造器的形参、代码块内
-
static修饰方法:
- 只能调用静态的结构
- 不能使用this、super
public static void show() { System.out.println("我是一个:" + nation); method01(); } public static void method01() { System.out.println("我是一个静态的方法"); }
- 非静态可以调用静态
public void method02() { System.out.println("我是一个非静态的方法"); method01(); }
- 成员变量:
-
属性什么时候使用static:
- 判断当前类的多个实例是否可以共享该成员变量
- 常把常量生成为static
-
方法说明时候使用static:
- 方法中如果都是静态变量,则需要声明为static
- 当工具类中的方法都生成为静态方法
package com.ygc.day01_static_exer;
/**
* @author: YGC
* @createTime: 2023/10/01 19:14
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description:
*/
public class CricleTest {
public static void main(String[] args) {
Circle circle = new Circle(3.5);
Circle circle1 = new Circle(3.5);
Circle circle2 = new Circle(3.5);
Circle circle3 = new Circle(3.5);
System.out.println(circle3.toString());
System.out.println(Circle.total);
}
}
class Circle {
double radius;
int id;
static int total;
public Circle() {
this.id = init;
init++;
total++;
}
public Circle(double radius) {
this();
this.radius = radius;
}
private static int init = 1001;
@Override
public String toString() {
return "Circle{" +
"radius=" + radius +
", id=" + id +
", total=" + total +
'}';
}
}
- 区别:
public class Array {
public static void main(String[] args) {
User user = null;
user.hello();
System.out.println(user.number);
}
}
class User {
public static int number = 1;
public static void hello() {
System.out.println("hello");
}
}
2. 单例模式
所谓的单例模式,就是采取一定的方法保证在整个软件的系统中,对某个类
只能存在一个对象实例
,并且该类只提供一个取得其对象实例的方法。
-
实现单例模式:
- 懒汉式:延迟加载
- (缺点)线程是不安全的
- (优点)在需要的时候创建,节省内存空间
//懒汉式 class GirlFriend { //1. 构造器私有化 private GirlFriend() { } //2. 声明类的对象 private static GirlFriend girlFriend = null; public static GirlFriend getGirlFriend() { if (girlFriend == null) { girlFriend = new GirlFriend(); } return girlFriend; } }
- 饿汉式:立即加载,随着类的加载,当前类的实例就已经创建了
- (优点)写法简单,内存中较早加载,所以速度较快、线程是安全的
- (缺点)内存的占用时间较长
//饿汉式 class Bank { //1. 构造器私有 private Bank() { } //2. 私有对象 private static Bank bank = new Bank(); //3.公开的方法供外界调用 public static Bank getBank() { return bank; } }
- 懒汉式:延迟加载
3. 代码块
用来初始化对象的信息(初始话类或对象的成员变量)
内部都可以用来输出语句、对成员变量初始化、按照申明的顺序执行
- 静态的代码块:使用static修饰的
- 使用:
- 随着类的加载而调用
- 类的加载只会执行一次,所以代码块只会执行一次
- 只能调用静态的结构
- 使用:
- 非静态的:未使用static修饰
- 使用:
- 随着对象的调用而调用
- 每次new一个对象都会调用
- 使用:
代码块赋值的执行顺序:
- 默认值
- 显示赋值
- 构造器
- 对象初始赋值
- 代码块
2和5谁先出现,谁先执行
1 => 2/5 => 3 => 4
4. final关键字
- 理解:最终
- final:可以修饰类、方法、变量
没有扩展的必要
- final修饰类:表示该类无法被其他的类继承
- final修饰方法:无法被重写
final class A {
}
class B extends A {/*Cannot inherit from final 'com.ygc.doy02_final.A'*/
}
- 修饰变量:一旦赋值就无法再更改了
5. 抽象类(abstract)
抽象类,不能在实例化,无需方法体
在开发时:多个类无法统一调用一个方法实现统一的功能(例如:求几何图形的面积),这样就可以将父类变成抽象类,让子类自己确定该方法需要什么样的功能,该方法无需方法体
继承抽象类,必须重写抽象方法
public class Student extends Person {
public void eat() {
System.out.println("学生应该多吃饭");
}
@Override
public void sleep() {
System.out.println("学生应该多睡觉");
}
}
public abstract class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void eat();
public abstract void sleep();
}
注【1】:
抽象类修饰类
- 此类称为抽象类,不能实例化
- 抽象类是有构造器的,子类继承时会默认使用super(),
- 抽象类中可以没有抽象方法
抽象类修饰类
- 此类称为抽象类,没有方法体
- 功能确定,只是不能确定具体实现的细节
- 子类必须重写父类的所有的抽象方法才能进行实例化
抽象类不能修饰:
代码块、属性、构造器
抽象类不能和那些关键字共用修饰:
不能用abstract修饰一个私有的方法、静态方法、final方法、final类
私有方法不能被重写,抽象方法必须被子类重写
静态方法可以直接通过类调用,而抽象的方法是不能被调用的
6.接口
接口的本质就是一个规范,必须需要去遵守,通常封装的是具体的功能
- 定义接口的关键字:interface
- 接口的内部结构的说明:
- 可以申明:
- 属性:public、static、final
- 只能是 public,缺省类型
- 方法:jdk8之前只能声明抽象方法、jdk8之后:声明静态的方法默认方法、jdk9声明私有方法
- 不能声明:
- 构造器、代码块
- 可以申明:
package com.ygc.day01_interfaceConcept;
public class InterfaceTest {
public static void main(String[] args) {
}
}
interface Flyable {
int Min_Speed = 0;
void fly();
}
interface assailable {
public abstract void attack();
}
class Bullet implements Flyable, assailable {
@Override
public void fly() {
System.out.println("让子弹飞一会");
}
@Override
public void attack() {
System.out.println("子弹可以穿透身体");
}
}
接口与类的实现关系:
- implements关键字实现接口
class Bullet extends aircraft implements Flyable, assailable
Bullet实际上是aircraft的一个子类,分别实现了多个接口
满足这这样的关系之后
- 类可以实现多个接口
- 类针对接口的多实现,一定程度上弥补了类单继承的局限性
- 类必须将实现的接口的抽象方法全部重写,方可实例化,否则此类仍然是一个抽象类
- 接口与类是是实现的关系
- 格式:class DD implements CC
- 接口与接口之间也可以继承,而且可以多继承
interface AA {
void app1();
}
interface BB {
void app2();
}
interface CC extends AA, BB {
}
class DD implements CC {
@Override
public void app1() {
}
@Override
public void app2() {
}
接口与接口的关系:
- 继承
interface bb {
void method1();
}
interface dd {
void method2();
}
interface cc extends bb,dd{
}
class zz implements cc{
@Override
public void method1() {
}
@Override
public void method2() {
}
接口 多态:
- 接口名 a = new 实现类();
- 多态的实现
- 可以创建接口的匿名对象
- 接口的匿名实现类的对象实现一个接口
package com.ygc.day01_interfaceConcept;
public class USBTest {
public static void main(String[] args) {
Computer computer = new Computer();
Print print = new Print();
computer.transferData(print);
//创建匿名对象
computer.transferData(new Camera());
//创建接口的匿名对象
USB usb1 = new USB() {
@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void stop() {
System.out.println("U盘停止工作");
}
};
computer.transferData(usb1);
//创建接口匿名实现的类的对象
computer.transferData(new USB() {
@Override
public void start() {
System.out.println("键盘开始工作");
}
@Override
public void stop() {
System.out.println("键盘结束工作");
}
});
}
}
interface USB {
void start();
void stop();
}
class Computer {
public void transferData(USB usb) {
System.out.println("设备连接成功");
usb.start();
System.out.println("计算机传输数据的具体细节");
usb.stop();
}
}
class Print implements USB {
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void stop() {
System.out.println("打印机停止工作");
}
}
面试题:【区分抽象类和接口】
共性: 都可以声明抽象方法
都不能实例化
不同:抽象类一定有构造器,接口没有构造器
类与类之间是继承关系,接口与接口之间是实现关系
练习
package com.ygc.day01_interfaceConcept.exer01;
/**
* @author: YGC
* @createTime: 2023/10/12 14:16
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description: 3、声明实现类美国人American,重写抽象方法,打印用刀叉吃饭
*/
public class American implements Eatable {
@Override
public void eat() {
System.out.println("用叉子吃饭");
}
}
package com.ygc.day01_interfaceConcept.exer01;
/**
* @author: YGC
* @createTime: 2023/10/12 14:15
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description: 声明实现类中国人Chinese,重写抽象方法,打印用筷子吃饭
*/
public class Chinese implements Eatable {
@Override
public void eat() {
System.out.println("用筷子吃饭");
}
}
package com.ygc.day01_interfaceConcept.exer01;
/**
* @author: YGC
* @createTime: 2023/10/12 14:14
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description: 1、声明接口Eatable,包含抽象方法public abstract void eat();
*/
public interface Eatable {
void eat();
}
package com.ygc.day01_interfaceConcept.exer01;
/**
* @author: YGC
* @createTime: 2023/10/12 14:17
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description: 声明实现类印度人Indian,重写抽象方法,打印用手抓饭
*/
public class Indian implements Eatable {
@Override
public void eat() {
System.out.println("用手抓饭");
}
}
package com.ygc.day01_interfaceConcept.exer01;
/**
* @author: YGC
* @createTime: 2023/10/12 14:18
* @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
* @description: 5、声明测试类EatableTest,创建Eatable数组,存储各国人对象,并遍历数组,调用eat()方法
*/
public class Test {
public static void main(String[] args) {
Eatable[] eatables = new Eatable[3];//多态性
eatables[0] = new American();
eatables[1] = new Chinese();
eatables[2] = new Indian();
for (int i = 0; i < eatables.length; i++) {
eatables[i].eat();
}
}
}
练习二
public int compareTo(Object o) {
if (this == o) {
return 0;
}
if (o instanceof ComparableCircle) {
ComparableCircle comparableCircle = (ComparableCircle) o;
return Integer.compare(this.getRadius(), comparableCircle.getRadius());
} else {
return 2;
}
7. 单元测试
使用单元测试需要使用注解@Test
可以替换原有的使用main方法测试的途径,使用更加方便
- 使用方法:
public class JuintTest {
@Test
public void run(){
}
}
注意事项:
- 必须是public的
- 必须是非抽象的
- 包含唯一的构造器
- 需要加上如下代码在vmoptions中重启idea才能在单元测试中使用键盘输入
-Deditable.java.test.console=true
- 将单元测试设置为一个模板:点击设置
@Test
public void test$var1$(){
$end$
}
8. 安装翻译插件
点击配置,注册有道账号
添加应用:在IDEA中输入对应的应用ID和密钥
9. 包装类
Java提供了两个类型系统,
基本数据类型
与引用数据类型
。使用基本数据类型在于效率,然而当要使用只针对对象设计的API或新特性(例如泛型),怎么办呢?例如:
//情况1:方法形参
Object类的equals(Object obj)
//情况2:方法形参
ArrayList类的add(Object obj)
//没有如下的方法:
add(int number)
add(double d)
add(boolean b)
//情况3:泛型
Set<T>
List<T>
Cllection<T>
Map<K,V>
为什么使用封装类
- 为了使基本数据类型具备引用数据类型变量的相关特征
- 自定义包装类
public class MyInteger {
int value;
public MyInteger() {
}
public MyInteger(int value) {
this.value = value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
转为包装类的对象,是为了使用专门为对象设计的API和特性
装箱:把基本数据类型转为包装类对象
基本数值---->包装对象(装箱)
Integer obj1 = new Integer(4);//使用构造函数函数
Float f = new Float(“4.56”);
Long l = new Long(“asdf”); //NumberFormatException
//推荐使用
Integer obj2 = Integer.valueOf(4);//使用包装类中的valueOf方法
拆箱:把包装类对象拆为基本数据类型
转为基本数据类型,一般是因为需要运算,Java中的大多数运算符是为基本数据类型设计的。比较、算术等
包装对象---->基本数值
Integer obj = new Integer(4);
int num1 = obj.intValue();
新特性:自动拆箱、装箱
Integer i = 4;//自动装箱。
i = i + 5;//等号右边:
//加法运算完成后,再次装箱,把基本数值转成对象。
字符串的拆装箱操做
int a = 10;
//String str = a;//错误的
String str = String.valueOf(a);
int a = 10;
String str = a + "";
方式3:通过包装类的构造器实现
int a = Integer.parseInt("整数的字符串");
double d = Double.parseDouble("小数的字符串");
boolean b = Boolean.parseBoolean("true或false");
int a = Integer.valueOf("整数的字符串");
double d = Double.valueOf("小数的字符串");
boolean b = Boolean.valueOf("true或false");
int i = new Integer(“12”);
总结
举例
@Test
public void test4() {
//装箱 基本数值---->包装对象(装箱)jdk 5.0
Integer integer = new Integer(1);//不推荐使用
Integer integer1 = Integer.valueOf(1);//推荐使用
//新特性
Integer num1 = 1;
//拆箱 包装对象---->基本数值
//jdk 5.0 之前的做法
Integer integer2 = new Integer(12);
int intValue = integer2.intValue();
System.out.println(intValue);
//新特性
integer2 = 1;
//字符串的装箱
String string = String.valueOf("123");
System.out.println(string);
String num = 1 + "";
//拆箱
int integer3 = Integer.parseInt(num);
System.out.println(integer3);
}
标签:System,void,高级,class,面向对象,static,println,public
From: https://www.cnblogs.com/ygcDiary/p/17776808.html