面向对象进阶(static、单例、代码块、继承)
面向对象进阶
静态关键字:static
static的作用、修饰成员变量的用法
package com.itheima.d1_static_field;
public class User {
// 在线人数信息:静态成员变量
public static int onLineNumber = 161;
// 实例成员变量
private String name;
private int age;
public static void main(String[] args) {
// 1、类名.静态成员变量
User.onLineNumber++;
// 注意:同一个类中访问静态成员变量,类名可以省略不写
System.out.println(onLineNumber);
// 2、对象.实例成员变量
// System.out.println(name);
User u1 = new User();
u1.name = "猪八戒";
u1.age = 36;
System.out.println(u1.name);
System.out.println(u1.age);
// 对象.静态成员变量(不推荐这样访问)
u1.onLineNumber++;
User u2 = new User();
u2.name = "孙悟空";
u2.age = 38;
System.out.println(u2.name);
System.out.println(u2.age);
// 对象.静态成员变量(不推荐这样访问)
u2.onLineNumber++;
System.out.println(onLineNumber);
}
}
162
猪八戒
36
孙悟空
38
164
static修饰成员变量的内存原理
static修饰成员方法的基本用法
package com.itheima.d2_static_method;
public class Student {
private String name;
private int age;
/**
实例方法:无static修饰,属于对象的,通常表示对象自己的行为,可以访问对象的成员变量
*/
public void study(){
System.out.println(name + "在好好学习,天天向上~~");
}
/**
静态方法:有static修饰,属于类,可以被类和对象共享访问。
*/
public static void getMax(int a, int b){
System.out.println(a > b ? a : b);
}
public static void main(String[] args) {
// 1、类名.静态方法
Student.getMax(10, 100);
// 注意:同一个类中访问静态成员 可以省略类名不写
getMax(200, 20);
// 2、对象.实例方法
// study(); // 报错的
Student s = new Student();
s.name = "全蛋儿";
s.study();
// 3、对象.静态方法(不推荐)
s.getMax(300,20);
}
}
100
200
全蛋儿在好好学习,天天向上~~
300
static实际应用案例:定义工具类
package com.itheima.d3_static_test;
public class Login {
public static void main(String[] args) {
// 验证码:
System.out.println("验证码:" + VerifyTool.createCode(10));
}
}
package com.itheima.d3_static_test;
public class Register {
public static void main(String[] args) {
// 验证码:
System.out.println("验证码:" + VerifyTool.createCode(5));
}
}
package com.itheima.d3_static_test;
import java.util.Random;
public class VerifyTool {
/**
私有构造器
*/
private VerifyTool(){
}
/**
静态方法
*/
public static String createCode(int n){
// 1、使用String开发一个验证码
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
// 2、定义一个变量用于存储5位随机的字符作为验证码
String code = "";
// 3、循环
Random r = new Random();
for (int i = 0; i < n; i++) {
int index = r.nextInt(chars.length());
// 4、对应索引提取字符
code += chars.charAt(index);
}
return code;
}
}
package com.itheima.d3_static_test;
public class ArrayUtils {
/**
把它的构造器私有化
*/
private ArrayUtils(){
}
/**
静态方法,工具方法
*/
public static String toString(int[] arr){
if(arr != null ){
String result = "[";
for (int i = 0; i < arr.length; i++) {
result += (i == arr.length - 1 ? arr[i] : arr[i] + ", ");
}
result += "]";
return result;
}else {
return null;
}
}
/**
静态方法,工具方法
*/
public static double getAverage(int[] arr){
// 总和 最大值 最小值
int max = arr[0];
int min = arr[0];
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
if(arr[i] < min){
min = arr[i];
}
sum += arr[i];
}
return (sum - max - min)*1.0 / (arr.length - 2);
}
}
package com.itheima.d3_static_test;
public class Test2 {
public static void main(String[] args) {
int[] arr = {10, 20, 30};
System.out.println(arr);
System.out.println(ArrayUtils.toString(arr));
System.out.println(ArrayUtils.getAverage(arr));
int[] arr1 = null;
System.out.println(ArrayUtils.toString(arr1));
int[] arr2 = {};
System.out.println(ArrayUtils.toString(arr2));
}
}
static的注意事项
package com.itheima.d4_static_attention;
public class Test {
// 静态成员变量
public static int onLineNumber;
// 实例成员变量
private String name;
public static void getMax(){
// 1、静态方法可以直接访问静态成员,不能访问实例成员。
System.out.println(Test.onLineNumber);
System.out.println(onLineNumber);
inAddr();
// System.out.println(name);
// 3、静态方法中不能出现this关键字
// System.out.println(this);
}
public void run(){
// 2、实例方法可以直接访问静态成员,也可以访问实例成员
System.out.println(Test.onLineNumber);
System.out.println(onLineNumber);
Test.getMax();
getMax();
System.out.println(name);
sing();
System.out.println(this);
}
public void sing(){
System.out.println(this);
}
// 静态成员方法
public static void inAddr(){
System.out.println("我们在黑马程序员~~");
}
public static void main(String[] args) {
}
}
static应用知识:代码块
代码块的分类、作用
package com.itheima.d5_static_codeblock;
public class TestDemo1 {
public static String schoolName;
public static void main(String[] args) {
// 目标:学习静态代码块的特点、基本作用
System.out.println("=========main方法被执行输出===========");
System.out.println(schoolName);
}
/**
特点:与类一起加载,自动触发一次,优先执行
作用:可以在程序加载时进行静态数据的初始化操作(准备内容)
*/
static{
System.out.println("==静态代码块被触发执行==");
schoolName = "黑马程序员";
}
}
package com.itheima.d5_static_codeblock;
public class TestDemo2 {
private String name;
/**
属于对象的,与对象一起加载,自动触发执行。
*/
{
System.out.println("==构造代码块被触发执行一次==");
name = "张麻子";
}
public TestDemo2(){
System.out.println("==构造器被触发执行==");
}
public static void main(String[] args) {
// 目标:学习构造代码块的特点、基本作用
TestDemo2 t = new TestDemo2();
System.out.println(t.name);
TestDemo2 t1 = new TestDemo2();
System.out.println(t1.name);
}
}
package com.itheima.d5_static_codeblock;
import java.util.ArrayList;
public class StaticCodeTest3 {
/**
模拟初始化牌操作
点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"
花色: "♠", "♥", "♣", "♦"
1、准备一个容器,存储54张牌对象,这个容器建议使用静态的集合。静态的集合只加载一次。
*/
// int age = 12;
public static ArrayList<String> cards = new ArrayList<>();
/**
2、在游戏启动之前需要准备好54张牌放进去,使用静态代码块进行初始化
*/
static{
// 3、加载54张牌进去。
// 4、准备4种花色:类型确定,个数确定了
String[] colors = {"♠", "♥", "♣", "♦"};
// 5、定义点数
String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
// 6、先遍历点数、再组合花色
for (int i = 0; i < sizes.length; i++) {
// sizes[i]
for (int j = 0; j < colors.length; j++) {
cards.add(sizes[i] + colors[j]);
}
}
// 7、添加大小王
cards.add("小🃏");
cards.add("大🃏");
}
public static void main(String[] args) {
System.out.println("新牌:" + cards);
}
}
static应用知识:单例设计模式
设计模式、单例模式介绍、饿汉单例模式
package com.itheima.d6_singleinstance;
/**
目标:学会使用恶汉单例模式设计单例类
*/
public class SingleInstance1 {
/**
static修饰的成员变量,静态成员变量,加载一次,只有一份
*/
// public static int onLineNumber = 21;
public static SingleInstance1 instance = new SingleInstance1();
/**
1、必须私有构造器:私有构造器对外不能被访问。
*/
private SingleInstance1(){
}
}
package com.itheima.d6_singleinstance;
public class Test {
public static void main(String[] args) {
// SingleInstance1 s1 = new SingleInstance1();
// SingleInstance1 s2 = new SingleInstance1();
// SingleInstance1 s3 = new SingleInstance1();
SingleInstance1 s1 = SingleInstance1.instance;
SingleInstance1 s2 = SingleInstance1.instance;
SingleInstance1 s3 = SingleInstance1.instance;
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s1 == s2);
}
}
懒汉单例模式
package com.itheima.d6_singleinstance;
/**
目标:设计懒汉单例
*/
public class SingleInstance2 {
/**
2、定义一个静态的成员变量用于存储一个对象,一开始不要初始化对象,因为人家是懒汉
*/
private static SingleInstance2 instance;
/**
1、私有构造器啊
*/
private SingleInstance2(){
}
/**
3、提供一个方法暴露,真正调用这个方法的时候才创建一个单例对象
*/
public static SingleInstance2 getInstance(){
if(instance == null){
// 第一次来拿对象,为他做一个对象
instance = new SingleInstance2();
}
return instance;
}
}
package com.itheima.d6_singleinstance;
public class Test2 {
public static void main(String[] args) {
// 得到一个对象
SingleInstance2 s1 = SingleInstance2.getInstance();
SingleInstance2 s2 = SingleInstance2.getInstance();
System.out.println(s1 == s2);
}
}
面向对象三大特征之二:继承
继承概述、使用继承的好处
package com.itheima.d7_extends;
public class People {
private String name;
private int 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;
}
}
package com.itheima.d7_extends;
public class Student extends People{
/**
独有的行为
*/
public void study(){
System.out.println(getName() + "学生开始学习~~~~~");
}
}
package com.itheima.d7_extends;
public class Teacher extends People{
/**
独有的行为
*/
public void teach(){
System.out.println("老师在快乐的教Java~~~~~");
}
}
package com.itheima.d7_extends;
public class Test {
public static void main(String[] args) {
// 创建子类对象,看是否可以使用父类的属性和行为
Student s = new Student();
s.setName("西门"); // 父类的
s.setAge(25);// 父类的
System.out.println(s.getName());// 父类的
System.out.println(s.getAge());// 父类的
s.study();
}
}
继承的设计规范、内存运行原理
package com.itheima.d8_extends_test;
/**
角色类 父类
*/
public class Role {
private String name;
private int age;
/**
共同行为
*/
public void queryCourse(){
System.out.println(name + "开始查看课程信息~~");
}
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;
}
}
package com.itheima.d8_extends_test;
public class Student extends Role{
// 独有属性
private String className;
// 独有行为
public void writeInfo(){
System.out.println(getName()
+ "说:今天学习感觉美美的,老师也是666~~~");
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
package com.itheima.d8_extends_test;
public class Test {
public static void main(String[] args) {
// 1、创建学生对象
Student s = new Student();
s.setName("张松松"); // 父类的
s.setAge(25); // 父类的
s.setClassName("Java999期"); // 子类的
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println(s.getClassName());
s.queryCourse(); // 父类的
s.writeInfo(); // 子类的
}
}
继承的特点
package com.itheima.d9_extends_feature;
public class ExtendsDemo {
public static void main(String[] args) {
// 子类是否可以继承私有的属性和行为呢?我认为可以的
Student s = new Student();
// System.out.println(s.age);
// s.run();
}
}
class C extends A{
}
class A{
}
class B{
}
class People{
private int age = 21;
private void run(){
System.out.println("人跑的很快~~");
}
}
class Student extends People{
}
继承后:成员变量、成员方法的访问特点
package com.itheima.d10_extends_field_method;
public class ExtendsDemo {
public static void main(String[] args) {
Wolf w = new Wolf();
System.out.println(w.name); // 子类的
w.showName();
}
}
class Animal{
public String name = "父类动物";
}
class Wolf extends Animal{
public String name = "子类动物";
public void showName(){
String name = "局部名称";
System.out.println(name); // 局部的
System.out.println(this.name); // 子类name
System.out.println(super.name); // 父类name
}
}
package com.itheima.d10_extends_field_method;
public class ExtendsDemo2 {
public static void main(String[] args) {
Student s = new Student();
s.run(); // 子类的
System.out.println("-----------");
s.go();
}
}
class People{
public void run(){
System.out.println("可以跑~~");
}
}
class Student extends People{
public void run(){
System.out.println("学生跑的贼快~~");
}
public void go(){
run(); // 子类的
super.run(); // 父类的
}
}
继承后:方法重写
package com.itheima.d11_extends_methodoverride;
public class NewPhone extends Phone{
/**
方法重写了
*/
@Override
public void call() {
super.call();
System.out.println("支持视频通话~~~");
}
/**
方法重写了
*/
@Override
public void sendMessage() {
super.sendMessage();
System.out.println("支持发送图片和视频~~~");
}
}
package com.itheima.d11_extends_methodoverride;
public class Phone {
public void call(){
System.out.println("打电话开始~~~");
}
public void sendMessage(){
System.out.println("发送短信开始~~~");
}
}
package com.itheima.d11_extends_methodoverride;
public class Test {
public static void main(String[] args) {
NewPhone huawei = new NewPhone();
huawei.call();
huawei.sendMessage();
}
}
继承后:子类构造器的特点
package com.itheima.d12_extends_constructor;
public class Animal {
public Animal(){
System.out.println("==父类Animal无参数构造器被执行===");
}
}
package com.itheima.d12_extends_constructor;
public class Cat extends Animal{
public Cat(){
super(); // 默认的,写不写都有,默认就是找父类无参数构造器
System.out.println("==子类Cat无参数构造器被执行===");
}
public Cat(String n){
super(); // 默认的,写不写都有,默认就是找父类无参数构造器
System.out.println("==子类Cat有参数构造器被执行===");
}
}
package com.itheima.d12_extends_constructor;
public class Test {
public static void main(String[] args) {
Cat c = new Cat();
System.out.println("------------");
Cat c1 = new Cat("叮当猫");
}
}
继承后:子类构造器访问父类有参构造器
package com.itheima.d13_extends_constructor2;
public class People {
private String name;
private int age;
public People() {
}
public People(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;
}
}
package com.itheima.d13_extends_constructor2;
public class Student extends People{
private String className;
public Student(){
}
public Student(String name, int age, String className) {
super(name, age);
this.className = className;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
package com.itheima.d13_extends_constructor2;
public class Test {
public static void main(String[] args) {
Student s = new Student("张三", 21, "99期");
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println(s.getClassName());
}
}
this、super使用总结
package com.itheima.d14_this;
public class Student {
private String name;
private String schoolName;
public Student() {
}
public Student(String name) {
// 借用兄弟构造器!
this(name, "黑马培训中心");
}
public Student(String name, String schoolName) {
this.name = name;
this.schoolName = schoolName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
}
package com.itheima.d14_this;
public class Test {
public static void main(String[] args) {
Student s1 = new Student("王亮", "清华大学");
System.out.println(s1.getName());
System.out.println(s1.getSchoolName());
Student s2 = new Student("王超");
System.out.println(s2.getName());
System.out.println(s2.getSchoolName());
}
}