1.面向过程&面向对象
1.1面向过程
// 计算三个长方形的面积和周长
// *** 面向过程编程
public class Home1 {
public static void main(String[] args) {
// 第一个
double w1 = 10;
double h1 = 10;
System.out.println("①周长:" + (w1+ h1)*2);
System.out.println("①面积:" + (w1*h1));
// 第二个
double w2 = 4;
double h2 = 5;
System.out.println("②周长:" + (w2+ h2)*2);
System.out.println("②面积:" + (w2*h2));
// 第三个
double w3 = 4;
double h3 = 5;
System.out.println("③周长:" + (w3+ h3)*2);
System.out.println("③面积:" + (w3*h3));
// 第n个(重复上面的代码)
}
}
1.2面向对象
// 计算三个长方形的面积和周长
// 面向对象: 封装一个长方形类(特征: w , h , 功能: 计算周长, 计算面积) , 然后创建对象, 调用对象的属性和方法。
public class Home2 {
public static void main(String[] args) {
Rect r1 = new Rect(10,10);
System.out.println("矩形1周长:" + r1.grith() );
System.out.println("矩形1面积:" + r1.area());
Rect r2 = new Rect(3,4);
System.out.println("矩形2周长:" + r2.grith() );
System.out.println("矩形2面积:" + r2.area());
}
}
class Rect{
double w;
double h;
public Rect(){}
public Rect(int w ,int h){
this.w = w;
this.h =h;
}
public double grith(){
return 2* (w+h);
}
public double area(){
return w*h;
}
}
对比
// 表示一个学生
public class Home3 {
public static void main(String[] args) {
String name = "alice";
String sex = "女生";
int age = 22;
String hobby = "看书";
System.out.println(name +"--" + sex +"---" + age +"---" + hobby +"----");
System.out.println("-----------------------");
Student stu = new Student();
stu.intro();
}
}
class Student{
String name;
String sex ;
int age ;
String hobby ;
public void intro(){
System.out.println(name +"--" + sex +"---" + age +"---" + hobby +"---- ");
}
}
2.方法的定义—return关键字
- 如果方法定义中有返回值类型的设置,需要使用return返回一个相同类型的数据
class Rect{
double w;
double h;
public Rect(){}
public Rect(double w, double h){
this.w = w;
this.h = h;
}
public double girth(){
return 2 * (w + h);
}
public double area(){
return w * h;
}
}
- 在方法中,可以使用return关键字,结束方法的运行
3.static关键字的使用
3.1static 关键字—修饰成员变量
-
用static修饰的成员变量不属于对象的数据结构
-
static修饰的变量属于类的变量,通常可以通过类名来引用static成员
-
static成员变量和类的信息一起存储在方法区,而不是在堆内存中
-
一个类的静态成员变量只有一份,而非静态成员对象有多份,即每个对象都有自己的非静态成员变
量。
public class Cat {
//猫的特征(描述对象)
String name;
String sex;
int age;
// 统计出猫(对象)的个数
static int count;
public Cat() {
count++;
}
public Cat(String name, String sex, int age){
this.name = name;
this.sex = sex;
this.age = age;
count++;
}
}
class TestCat {
public static void main(String[] args) {
//count 是Cat类中的静态变量,可以通过类名直接访问静态变量
System.out.println(Cat.count); // 0
Cat cat = new Cat();
cat.age = 3;
cat.sex = "公猫";
cat.name = "tom";
//cat.count++;
//Cat.count++; // 增加了一只猫
//System.out.println(cat.count); // 1
System.out.println(Cat.count);
Cat c1 = new Cat();
c1.age = 2;
c1.sex = "公猫";
c1.name = "jerry";
//cat.count++;
//Cat.count++;
System.out.println(Cat.count);
}
}
3.2static关键字—修饰方法
-
类中的方法,通常都会涉及到堆具体对象的操作,这些方法在调用时,需要隐式的传递对象的引
用。
void print(){
System.out.println(this.x + “,” + this.y);
}
-
static修饰的方法则不需要针对对象进行操作,其运行结构仅仅与输入的参数有关系。调用时候直
接通过类名引用。
Math.sqrt(100)
-
static修饰的方法是属于类的方法,通常用于提供工厂方法,或者工具方法。
-
static修饰的方法,调用的时候没有具体的对象,因此static修饰的方法不能调用非静态成员变量和
成员方法。
//静态方法中,无法调用非静态成员变量和非静态的成员方法
// *** 非静态成员变量和非静态的成员方法,属于对象的, 只能通过对象调用。
// *** 静态的成员变量和成员方法,属于类的,可以通过类名直接调用(也可以通过对象的引用进行调用)。
public class Dog {
String name;
String sex;
static int count;
//输出狗的数量。以及当前这只狗的属性
public void print(){// 非静态方法: 属于对象,通过对象进行调用。
System.out.println("一共:" + count);
System.out.println("名字:" + this.name + ", 性别" + this.sex);
}
//增加狗的数量:只要new了一个对象,就调用add方法,修改狗的总数
public static void add(){
count++;
/*
System.out.println("当前增加的狗的名字:" + this.name); // 静态方法:属于类,name是非静态的成员变量,属于对象的。
this.print(); // print() 是非静态方法,属于对象,通过对象来调用。
*/
}
public static void main(String[] args) {
count++;
add();
//name ="xx"; // 非静态的。不能直接在静态方法中使用
Dog dog = new Dog();
dog.name = "tom";
dog.sex = "公";
dog.print();
}
}
4.final关键字
-
修饰类
- final关键字修饰的类不可以被继承
- 对于一些类,设置了final修饰,可以避免滥用继承造成的危害
-
修饰方法
-
final关键字修饰的方法可以不被重写
-
防止子类在定义自己的方法的时候,不经意被重写。
-
public class FianlDemo {
}
//final修饰的类不能被继承
//*** jdk中的很多类,都是final修饰的
final class A{}
//class B extends A{}
class Shape{
// final修饰的变量,就不可以修改数据值。
static final double PI = 3.14; // static + final 修饰成员变量,本质定义的是常量。
int x, y;
// final修饰的方法,不允许被子类重写
final public void print(){
//* 常量:为了方便程序中使用常量,常量定义为 static + final修饰,常量都用大写字母表示(常量是多个单词,使用_分割)
/*Math.PI;
Integer.MAX_VALUE;
Integer.MIN_VALUE;*/
System.out.println("x: " + x+" y: " + y);
}
}
/*
class SanJiao extends Shape{
//父类的方法是final修饰的,子类不能被重写
@Override
public void print() {
System.out.println("*****x: " + x+" y: " + y);
}
}*/
-
修饰变量
-
final修饰成员变量,意为不可以改变。该成员变量需要在初始化的时候赋值,对象一旦创
建,即该值不可以改变。
-
public class FinalDemo1 {
//创建数组,长度固定为5
static final int LENGTH =5;
// 1~100的素数
static final int MAX = 100;
//连接mysql数据库
static final int PORT = 3306;
public static void main(String[] args) {
int[] a = new int[FinalDemo1.LENGTH];
for (int i = 0; i <= a.length; i++){
a[i] =i;
}
for (int i = 2; i <= FinalDemo1.MAX; i++){
return ;
}
//使用PORT
System.out.println(FinalDemo1.PORT);
}
}
5.对象数组
所谓对象数组,对象数组的元素不是基本类型,而是引用类型。
5.1对象数组的初始化和使用
对象数组的初始化和基本类型数组的初始化方式一样,只不过元素是对象引用而已。
对象数组创建之后,元素的默认值是null.
Point
class Point{
int x;
int y;
public Point(){
}
public Point(int x, int y){
this.x = x;
this.y = y;
}
public void print(){
System.out.println("("+x+","+y+")");
}
// 计算两个点之间的距离
public double distance(Point p){
// this是一个点,point是另一个点
return Math.sqrt(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2));
}
}
对象数组的使用
// 对象数组: 数组元素存储的是对象的引用地址
public class ArrayDemo {
public static void main(String[] args) {
Point[] ps; // 数组(对象数组)
ps = new Point[4]; // 表示数组的长度 --- 数组的元素默认值是null
ps[0] = new Point(2,2);
ps[1] = new Point(3,3);
ps[2] = new Point(4,4);
ps[3] = new Point(5,5);
for(int i = 0; i < ps.length; i++) {
ps[i].print();
}
Point p1 = ps[0]; //把对象的引用地址赋值给另一个引用
p1.x = 10;
p1.y = 10;
System.out.println("------------------------数组元素的xy被修改了");
for(int i = 0; i < ps.length; i++) {
ps[i].print();
}
Point p2 = new Point(3,3);
ps[1] = p2;
System.out.println("------------------------");
for(int i = 0; i < ps.length; i++) {
ps[i].print();
}
System.out.println("------------------------");
// 赋值
ps[0] = ps[1] = ps[2] = ps[3]; // 4个指向同一个对象
ps[2].x = 7;
ps[3].y = 8;
for(int i = 0; i < ps.length; i++) {
ps[i].print();
}
}
}
5.2二维数组
数组的元素可以为任何类型,也包括数组类型
- 数组的元素可以为任何类型,也包括数组类型。
int[][] arr = new int[3][];
arr[0] = new int[5]
arr[1] = new int[4]
arr[2] = new int[5]
- 数组类型数组的初始化
int[][] = {{1,3,2},{4,5,6}}
Point[][] ps = {{new Point(1,2),new Point(1,2)},{new Point(1,2),new
Point(1,2)}}
如果每个数组的元素长度相同:
int[][] = new int[3][5]
- 二维数组的使用
public class ArrayDemo2 {
public static void main(String[] args) {
int[][] a1 = new int[4][5]; // 数组放多少个数据?
//给二维数组赋值
for(int i = 0; i < a1.length; i++) { // a1.length 是第一维的长度
int[] datas = a1[i];
for(int j = 0; j < datas.length; j++) { //datas.length 是第二维的长度(5)
datas[j] = j + i;
}
}
int[][] ds = new int[10][10];
int count = 1;
for(int i = 0; i < ds.length; i++){
for(int j = 0; j < ds[i].length; j++){
ds[i][j] = count++;
}
}
System.out.println("输出数组:");
for(int i = 0; i < ds.length; i++){
for(int j = 0; j < ds[i].length; j++){
System.out.print(ds[i][j] + "\t");
}
System.out.println();
}
}
}
- 对象类型的二维数组的使用
//创建一个Point类型的二维数组,然后存放Point对象的引用, 计算出两个点之间的距离
public class ArrayDemo3 {
public static void main(String[] args) {
Point[][] ps = new Point[5][2]; //10个点,分成5个组,每个组两个点
//数组初始化(点的x,y使用随机数生成)
Random rand = new Random();
for(int i = 0; i < ps.length; i++) {
for(int j = 0; j < ps[i].length; j++) {
Point p = new Point(); // 创建10个Point对象
p.x = rand.nextInt(10);
p.y = rand.nextInt(10);
ps[i][j] = p;
}
}
//计算
for(int i = 0; i < ps.length; i++) {
Point p1 = ps[i][0];
Point p2 = ps[i][1];
double line = p1.distance(p2);
//System.out.println(p1.print()+"\n"+p2.print());
System.out.println("line: " + line);
}
}
}
6.什么是抽象类
6.1abstract关键字
-
用abstract关键字修饰的类称之为抽象类。
-
抽象类不能实例化,抽象类的意义在于“被继承”。
-
抽象类为子类“抽象”出公共部分,通常也定义了子类所必须实现的抽象方法。
// *** abstract : 抽象, java中的关键字, 在类面前,表示是抽象类,在方法面前,表示是一个抽象方法
// *** 抽象类中: 成员变量 , 成员方法 (实现了的方法,和没有实现的抽象方法)
abstract class Animal{
int age; // 年龄
double hp; // 生命值
public Animal(){
System.out.println("animal.......,所有动物的父类。");
}
public void eat(String food){
System.out.println("吃:" + food);
}
//抽象方法:用abstract修饰,没有方法体
// ** 休息的方式不同,定义一个方法,不实现这个方法,让子类自己实现。 ----规范了所有子类,必须有sleep方法
public abstract void sleep();
public abstract void sing();
}
6.2继承抽象类
- 一个抽象类可以有抽象方法,也可以有非抽象方法
- 一个类继承了抽象类,那么必须实现父类的抽象方法,除非该类依然定义为抽象类。
// ** Bird继承了抽象类,就需要实现父类的抽象方法。否则Bird依然设置为抽象类
//** Bird作为子类,继承的父类的所有抽象方法,都需要实现。如果没有具体的函数体,就空实现(解决编译错误)
public class Bird extends Animal {
@Override
public void sleep(){
System.out.println("鸟在鸟窝里休息........");
}
@Override // 空实现: 方法体没有任何代码, 为了解决编译错误。
public void sing() {}
public void egg() {
System.out.println("鸟下蛋了....");
}
}
// ** 抽象类的子类,依然是一个抽象类,那么这个子类可以不实现父类中的抽象方法,也可以实现。
abstract class WoNiu extends Animal{ // 蜗牛类
@Override
public void sleep(){
System.out.println("蜗牛在树叶上休息.........");
}
}
class GoldWoNiu extends WoNiu{
@Override // 空实现
public void sing() {
}
public void run() {
System.out.println("黄金蜗牛在沙滩上爬......");
}
}
class TestAnimal{
public static void main(String[] args) {
//Animal animal = new Animal(); // ----抽象类不能被实例化
//WoNiu woNiu = new woNiu(); // ----抽象类不能被实例化
Animal a1 = new Bird(); // 向上造型
a1.sing();
a1.sleep();
//a1.egg(); //编译错误: 编译的时候,a1是Animal类型,没有egg方法。无法调用。
// **两种转型方法
if (a1 instanceof Bird){
Bird b1 = (Bird)a1; // 如果子类有某个特殊方法不能使用,那么只能强转后才能使用
}
if (a1.getClass() == Bird.class) {
Bird b2 = (Bird)a1;
}
WoNiu ww = new GoldWoNiu();
GoldWoNiu gwn = new GoldWoNiu();
Animal a = new GoldWoNiu();
//调用run方法
gwn.run();
if (a instanceof GoldWoNiu) {
GoldWoNiu gg1 = (GoldWoNiu)a;
gg1.run();
}
if (ww.getClass() == GoldWoNiu.class) {
GoldWoNiu gg2 = (GoldWoNiu) ww;
gg2.run();
}
}
}