为什么需要学习static?
静态变量,为所有对象共享使用
static概述 : 静态的 / 共享的
static的特点
1.静态变量属于类,而不属于具体的对象
2.在静态环境中,只能够访问静态变量,不能够访问非静态变量
3.在非静态环境下,既能够访问静态变量,也能够访问非静态变量
4.静态变量的访问格式:
1.通过对象访问
2.通过类名访问
3.通过set方法访问
5.当有一个对象修改了static属性的值,任意一个对象都会被影响
6.静态修饰方法或者变量有意义吗?
变量: 共享
方法: 方法是用来完成特定功能的,给别人调用,而静态修饰的方法正好可以通过类名直接访问
方便调用,不需要创建对象,常用来编写工具类 Math
书写工具类的步骤
1.构造方法私有
2.方法成员全部静态化
7.static环境中不能够出现this和super
8.static不仅可以修饰变量和方法,还能够修饰代码块,以及类(保证是内部类)
面试题:
实例变量和类变量的区别?
package com.sxt.staticdemo;
public class StaticDemo01 {
static int num = 20;
public static void main(String[] args) {
Student.staticMethod();
Student s1 = new Student("貂蝉", 25, "中国");
s1.setCountry("中国");
Student s2 = new Student("西施", 26);
Student s3 = new Student("老王", 33);
s3.setCountry("美国");
Student.country = "阿富汗";
s1.show();
s2.show();
s3.show();
System.out.println(num);
XXXUtils.utils1();
}
static {
}
static class InnerClass {
}
}
class XXXUtils {
private XXXUtils() {}
public static void utils1() {
System.out.println("XXXUtils.utils1()");
}
public static void utils2() {
System.out.println("XXXUtils.utils2()");
}
}
class Student {
String name;
int age;
static String country; // 国籍
public Student() {
super();
}
public Student(String name, int age, String country) {
super();
this.name = name;
this.age = age;
Student.country = country;
}
public Student(String name, int age) {
super();
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 String getCountry() {
return country;
}
public void setCountry(String country) {
Student.country = country;
}
public void show() {
System.out.println("Student [name=" + name + ", age=" + age + ", country=" + country + "]");
}
public static void staticMethod() {
System.out.println("Student.staticMethod()");
}
}
代码块: 大括号包裹的就称为代码块
代码块的分类:
1.局部代码块: 定义在局部位置,限定局部变量的作用域
2.构造代码块: 定义在成员位置,用来抽取多个构造方法中的重复代码,可以简化编程
在构造方法之前执行,并且每次创建对象前都会执行一次,由于构造方法之前执行
3.静态代码块:
定义在成员位置,在构造代码块和构造方法之前执行,并且只会执行一次
作用:
a.用来加载一些预定义的资源,比如说数据库的连接,配置文件的读取
b.用来初始化静态成员
执行时机和执行顺序:
静态代码块 > 构造代码块 > 构造方法
构造方法在对象创建的时候执行,可以执行多次
构造代码块在对象创建之前执行,可以执行多次
静态代码块在类第一次出现(类加载)/或者第一次使用的时候执行,只能够执行一次
4.同步代码块(后面讲解多线程的时候讲解)
package com.sxt.staticdemo;
public class StaticDemo02 {
public static void main(String[] args) {
Code c = new Code();
Code c1 = new Code(10);
Code c2 = new Code(10, 20);
}
static {
System.out.println("StaticDemo02我是静态代码块");
}
}
class Code {
int num1 = 5;
int num2 = 10;
static int num3;
static {
System.out.println("我是静态代码块1");
num3 = 30;
}
static {
System.out.println("我是静态代码块2");
}
// 2.构造代码块
{
System.out.println("我是构造方法");
}
public Code() {
// System.out.println("我是构造方法");
System.out.println("Code");
}
public Code(int num1) {
// System.out.println("我是构造方法");
this.num1 = num1;
System.out.println("Code(int num1)");
}
public Code(int num1, int num2) {
// System.out.println("我是构造方法");
this.num1 = num1;
this.num2 = num2;
System.out.println("public Code(int num1, int num2)");
synchronized (new Object()) {
}
}
public void method() {
{
int num = 10;
System.out.println(num);
}
{
int num = 20;
System.out.println(num);
}
}
}
为什么需要有包?
1.处理同一个中的重名问题
2.分门别类地管理Java文件
包的概述: 本质就是文件夹
包的格式:
package 包名1.包名2.包名n…
包的使用:
import java.util.Scanner;
import java.util.*;
包的特点:
1.同包下的类相互调用不需要导包
2.在同一个类中同时使用不同包的同名类,需要显示导入,例如后面学习数据库的时候 Java中的日期类:java.util.Date 数据库中的日期类: java.sql.Date
将数据库中的日期转换成Java的日期
3.如果一个类没有包,那么该类就成为了孤立的类,不能够被别人使用
4.包的声明必须出现在类的第一句
5.如果希望导入一个包中所有的类: import xxx.xxx.xx.*
6.某些包中的类是不需要我们导入的,系统会自动导入 例如lang(Java的核心包)包
7.在自己写一个类的时候千万不要和系统类重名
JRE中提供给我们常见的包:
java.lang 包含了Java中的一些核心类 String Object Math Arrays
java.util 工具包
java.io 输出输出流相关的类
java.net 网络包
快捷键: 一键导包 Ctrl + Shift + O
package com.sxt.packagedemo;
import java.util.Date;
import java.util.Scanner;
public class PackageDemo01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Student s = new Student();
com.sxt.packageBdemo.Student s2 = new com.sxt.packageBdemo.Student();
Date sqlDate = new Date(1000L);
java.util.Date javaDate = new java.util.Date(sqlDate.getTime());
Math.random();
}
}
练习
1、创建Employee类
属性:姓名,年龄,性别,工资。
方法:显示对象的属性值,工作。
要求:属性要封装
创建3个对象
构造函数重载
package com.sxt.practice;
public class Practice01 {
public static void main(String[] args) {
Employee e = new Employee();
// 通过set方式
e.setName("哈哈");
e.setAge(18);
e.setGender("男");
e.setSalary(3000);
e.show();
// 通过构造方法
Employee e2 = new Employee("呵呵", 20);
e2.setGender("女");
e2.setSalary(40000);
e2.show();
// 仅通过构造方法
Employee e3 = new Employee("嘿嘿", 9, "女", 500000);
e3.show();
}
}
class Employee {
private String name;
private int age;
private String gender;
private double salary;
// Ctrl + Shift + F
public Employee() {
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(String name, int age, String gender, double salary) {
this.name = name;
this.age = age;
this.gender = gender;
this.salary = salary;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void show() {
System.out.println("Employee [name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + "]");
}
public void work() {
System.out.println("员工工作");
}
}
、定义一个“点”(Point)x y set get类用来表示二维空间中的点。要求如下:
A 可以生成具有特定坐标的点对象。
B 提供可以设置坐标的方法。
C 提供可以计算该点距离另一点距离的方法。
D 提供可以计算三个点构成图形的面积的方法。
面积可以使用海伦公式:边长分别为a,b,c p=(a+b+c)/2
s=Math.sqrt(p*(p-a)(p-b)(p-c))
package com.sxt.practice;
public class Practice04 {
public static void main(String[] args) {
Point p1 = new Point(1, 1);
Point p2 = new Point(2, 2);
Point p3 = new Point(2, 1);
System.out.println(p1.getDistance(p2));
System.out.println(p1.getArea(p1, p2, p3));
System.out.println(p1.getArea(p2, p3));
}
}
class Point {
private double x;
private double y;
public Point() {
}
// A 可以生成具有特定坐标的点对象。
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/*
* C 提供可以计算该点距离另一点距离的方法。 返回值类型: double 参数列表: Point p1, Point p2 方法名: getDistance
*/
public double getDistance(Point p1, Point p2) {
double distance = 0.0;
double _x = p1.getX() - p2.getX();
double _y = p1.getY() - p2.getY();
distance = Math.sqrt(_x * _x + _y * _y);
return distance;
}
/*
* C 提供可以计算该点距离另一点距离的方法。 返回值类型: double 参数列表: Point p 方法名: getDistance 一个点到当前点的距离
*/
public double getDistance(Point p) {
double distance = 0.0;
double _x = p.getX() - this.getX();
double _y = p.getY() - this.getY();
distance = Math.sqrt(_x * _x + _y * _y);
return distance;
}
/*
* D 提供可以计算三个点构成图形的面积的方法。 面积可以使用海伦公式:边长分别为a,b,c p=(a+b+c)/2
* s=Math.sqrt(p*(p-a)*(p-b)*(p-c))
*/
public double getArea(Point p1, Point p2, Point p3) {
double a = p1.getDistance(p2);
double b = p1.getDistance(p3);
double c = p2.getDistance(p3);
double p = (a + b + c) / 2;
double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));
return s;
}
public double getArea(Point p1, Point p2) {
double a = p1.getDistance(p2);
double b = p1.getDistance(this);
double c = p2.getDistance(this);
double p = (a + b + c) / 2;
double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));
return s;
}
public double getX() {
return x;
}
// B 提供可以设置坐标的方法。
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
// B 提供可以设置坐标的方法。
public void setY(double y) {
this.y = y;
}
}
定义一个QQ,属性:nickName,id,password,age 方法:chat(QQ q) 打印正在跟谁聊天
changePassword(String newPassword) 给 q 修改密码为 newPassword
package com.sxt;
public class Practice01 {
public static void main(String[] args) {
QQ qq1 = new QQ("尼古拉斯", "7758520", "123456", 35);
QQ qq2 = new QQ("斯巴达", "77585202", "123321", 35);
qq1.chat(qq2);
System.out.println("原密码:" + qq1.getPassword());
qq1.changePassword("7777777");
System.out.println("新密码:" + qq1.getPassword());
}
}
class QQ {
private String nickName;
private String id;
private String password;
private int age;
public QQ() {
}
public QQ(String nickName, String id, String password, int age) {
this.nickName = nickName;
this.id = id;
this.password = password;
this.age = age;
}
public void chat(QQ qq) {
System.out.println(this.getNickName() + "正在和" + qq.getNickName() + "聊天");
}
public void changePassword(String newPassword) {
this.password = newPassword;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("QQ [nickName=" + nickName + ", id=" + id + ", password=" + password + ", age=" + age + "]");
}
}
package com.sxt;
import javax.swing.text.Position;
/*
* 3、定义一“圆”(circle)类,圆心为“点”point类,构造一圆,求圆的周长和面积,并判断某点与圆的关系。
class cirlcle{
double radius;
Point point;
}
OOA:分析有多少个对象,有多少个对象就写多少个类
OOD:分析类与类之间的关系
OOP:在主方法中尽量不要出现逻辑业务计算代码,只能够创建对象和调用方法和属性即可
* */
public class Practice02 {
public static void main(String[] args) {
Point point = new Point(1, 1);
Point circleHeart = new Point(1, 1);
Circle c = new Circle(1, circleHeart);
System.out.println("周长:" + c.getPerimeter());
System.out.println("面积:" + c.getArea());
System.out.println("点和圆的位置关系:" + c.judgePointAndCirleRelationShip(point));
}
}
class Circle {
/*
* 求圆的周长
* 返回值类型:double
* 参数类型: 无参
* 方法名:getPerimeter
* */
private double r;
private Point p;
public Circle() {
super();
}
public Circle(double r, Point p) {
super();
this.r = r;
this.p = p;
}
public double getPerimeter() {
return 2 * Math.PI * this.r;
}
/* 求面积
* 返回值类型: double
* 参数列表: 无参
* 方法名: getArea
* */
public double getArea() {
return Math.PI * Math.pow(this.r, 2);
}
/* 判断某点与圆的关系
* 返回值: 3种状态String
* 参数列表: 圆(this) 点(Point p)
* 方法名: judgePointAndCirleRelationShip
* */
public String judgePointAndCirleRelationShip(Point p) {
String position = null;
//计算圆心点到传入的距离
double distance = p.getDistance(this.p);
if (distance > this.r) {
position = "点在圆外";
} else if (distance < this.r) {
position = "点在圆内";
} else {
position = "点在圆上";
}
return position;
}
}
class Point {
private double x;
private double y;
public Point() {
super();
}
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
//计算一个点到另一个点的距离
public double getDistance(Point p) {
double distance = 0.0;
double _x = this.getX() - p.getX();
double _y = this.getY() - p.getY();
distance = Math.sqrt(_x * _x + _y * _y);
return distance;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}