JAVA通过看代码学习类与对象的知识---学习笔记

 视频地址:http://www.51zxw.net/study.asp?vip=5570608

      本节内容是根据51自学网的壁虎老师讲解的java视频教学做的笔记,0基础的看51自学网壁虎老师的视频是最恰当不过的,我看了三四年了,反反复复的看好几遍(其实每次看都木有看完,看了前几章就不看了,过了好久好久又想用java还去看一遍,每次又木有看完,没有把基础全看完,所以java一直学不会,这次咬牙坚持把最后一章节看完了,前面的知识点都学过好多遍了,都通用,重点在后边,不知道有谁象我这样的学习,这是非常非常不好的习惯,要坚持看完,看完多练多总结!不多说了,说多了都是泪。)为了弥补这多年的坑,最后一次看壁虎老师的视频了,也就是把java基础学完了,以后再也不看他视频了,浪费时间,直接看笔记回忆快。可以考虑看看其他老师的视频,每个人的学习方法和经历都不一样,更可况其他老师的教学方式也不一样,多看一个老师的,说不定你获得的知识也不一样;

 

现在把这些知识点都总结下,与大家分享。---故这篇文章适合看过51自学网壁虎老师的视频的同学

   先来简介下这个java基础的由来:壁虎老师当时在51自学网录制这个视频的时候才17岁,还是边学边教的,点击率现在应该破千万了把!(我是12年注册51自学网的,当时大学有java这么课程,我还二十多岁了,还以为壁虎老师是个经验丰富的编程高手,想不到啊!)我是最近搜索才知道,他是前印象笔记的程序员,现在是高手了应该,也自己开课了,我去看了他最近一两年做的视频,每集五六分钟的风格,感觉还是没有以前好了,就像他自己说的,只有初学者讲出来的才适合初学者听,经验丰富的其实以为你基础都已经懂了。我也是百度才知道这些的。

   好了,基本情况介绍完了,壁虎老师的课程讲了啥,我截图了,实战6-18至6-31都木有看,木有什么技术含量,我只记知识点。我们只通过代码去回忆所学过的知识点。

现在开始:

A6_1 ~ A6_4 (略!)只是简单介绍,跳过

 

A6_4 创建类与对象(最近没看该集,直接跳过)

public class A6_4{ //这个是一个A6_4(第6章第4节)的类
	public static void main(String[] args){
		Person MyPerson=new Person(); //这Person人,就是对象,new创建一个MyPerson的对象
		MyPerson.name="小明放到"; //这个对象叫小明
		System.out.println(MyPerson.name);
		MyPerson.eat();
	}
}

 

A6_5 面向对象与内存解析

public class A6_5{
	public static void main(String[] args){
		Person One=new Person();//新建一个one对象,储存在一个位置
		Person Two=new Person();//新建另一个two对象,储存在另一个位置
		Two.age=12;//这个two对象从它之中去age空间并赋值
		System.out.println(Two.age);
		System.out.println(One.age);
		One.eat();//这个one对象从one之中去eat空间并赋值
		Two.eat();//这个two对象从two之中去eat空间并赋值
		
	}
}

 

 

A6_6 有参无返回间的调用(最近没看该集,直接跳过)

public class A6_6{
	public static void main(String[] args){//main函数,一般用来测试
		Person per=new Person();
		int age=per.getAge(18);//age()中有参,18就是参数
		System.out.println(age);
	}
}

 

 

A6_7 有参无返回间的调用(最近没看该集,直接跳过)

public class A6_7{
	public static void main(String[] args){
		Test MyTest=new Test();//无参
		System.out.println(MyTest.name);
	}
}

 

A6_8 无

 

 

A6_9  return和多参方法

class Dog{
	String name;
	public String print(String n,int a,char b){
		System.out.println("n="+n);
		System.out.println("a="+a);
		System.out.println("b"+b);
		return n;//返回方法制定的类型值,这个值总是确定的,可以把n改“sdsd”字符串
	}
	public void str(int a){
		if(a==0){
			System.out.println("你好");//不会输出,因为下面有return
		}else if(a==1){
			return;//结束方法的执行,“你好”、“我很好”都不会输出
		}
		System.out.println("我很好");//不会输出,因为上面有return
	}
}
public class A6_9{
	public static void main(String[] args){
		Dog A=new Dog();
		A.print("小明",12,'男');//调用print方法的三个参数
	}
}
/*编译结果:
n=小明
a=12
b男
*/

 

 

A6_10 toString方法

//在java中,所有对象都有toString()这个方法
class Cat{
	String name;
	int age;
	public String toString(){//不定义toString方法的话,输出的不是内容,而是输出内存地址
		return "我的姓名:"+name+"我的年龄:"+age;
	}
}
//哈希码值:对象的内存地址
public class A6_10{
	public static void main(String[] args){
		//String name=new String("你好");
		//sysSystem.out.println(name);//同等于sysSystem.out.println(name.toString);
		Cat one=new Cat();
		one.name="小明";
		one.age=12;
		Cat two=new Cat();
		two.age=16;
		two.name="小红";
		System.out.println(one);//默认调用.toString相当于one.toString
		System.out.println(two);//默认调用.toString相当于two.toString
	}
}
/*编译结果:
我的姓名:小明我的年龄:12
我的姓名:小红我的年龄:13
*/

 

 

A6_11 this关键字

class Cat{
	String name;
	int age;
	String color;
	public void set(String name,int age,String color){
		this.name=name;//有this为成员变量
		this.age=age;
		this.color=color;
	}
	public String toString(){
		return "姓名:"+name+"\t年龄:"+age+"\t颜色:"+color;
	}
	public Cat abc(){
		return this;//当前对象的引用
	}
}
public class A6_11{
	public static void main(String[] args){
		Cat one=new Cat();
		Cat two=new Cat();
		one.set("第一只猫",5,"黑色");
		two.set("第二只猫",6,"紫色");
		Cat three=new Cat();
		three=two.abc();//把two返回abc()赋值给three
		//three=two;
		System.out.println(one);
		System.out.println(two);
		System.out.println(three);
	}
}
/*编译结果:
姓名:第一只猫 年龄:5 颜色:黑色;
姓名:第二只猫 年龄:6 颜色:紫色;
姓名:第二只猫 年龄:6 颜色:紫色;
*/

 

 

A6_12 理解封装

//封装:不想给别人看的进行封装,可以告诉的就公开

class Student{
	private String name;//private私有的,加这个只能在自己的类访问它,其他类不能访问,即不想告诉别人,隐藏起来
	private int age;
	private char gender;//
	//给gender提供一个共有的方法setGender,也就是可以公开的方法
	public void setGender(char gender){//命名规范,看到set开头就知道给成员属性做设置
		if(gender=='男'||gender=='女'){//增加控制用户乱输入,即只能输入男或女,不能输入其他内容
			this.gender=gender;
		}else{
			System.out.println("请输入正确的性别");//输入其他内容就提醒
		}
	}
	//不能直接输出了,需要定义一个方法
	public char getGender(){//命名规范,看到get开头取得意思
		return this.gender;//return gender;可以这么写,因为没有重名,加个this容易分清
	}
}
public class A6_12{
	public static void main(String[] args){
		Student one=new Student();
		//one.gender('f');这个是没有加private前可以直接传值,加private后还这么写就会报错
		one.setGender('男');
		System.out.println(one.getGender());
	}
}

 

 

A6_13 方法重载

import java.util.Arrays;//数组的排序

//重载指在一个类中有相同的名字,但是参数不同的多个方法,调用时根据参数不同的参数列表选择对应的方法

class Student{
	//max方法名一样方便记忆,只要参数不一样就行
	public void max(int a,int b){//两个int类型
		System.out.println(a>b?a:b);//a>b?a:b三元运算符,判断a是否大于b,大于选择a,否则选择b	
	}
	public void max(double a,double b){//两个double类型
		System.out.println("第二个方法"+(a>b?a:b));
	}
	public void max(double a,double b,double c){//三个double类型
		double max=a>b?a:b;
		System.out.println("第三个方法"+(max>c?max:c));//max>c?max:c记得加括号,否则计算机识别错误
	}
}
public class A6_13{
	public static void main(String[] args){
		double[] arr={43.5,5.46,61.5,7.6,7.8};//根据参数的不同自动选择哪个方法,这个是double
		Arrays.sort(arr);//数组排序,Arrays中有很多方法名都是sort,就是参数不一样
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
			
	}
}

 

 

A6_14 构造函数方法

/*
构造方法(构造函数):使用new+构造方法创建一个新的
构造函数是定义在java类中的一个用来初始化对象的函数
构造函数与类同名没有返回值
Student one=new Student()
*/

class Cat{
	private String name;
	private int age;
	//Cat()其实就是构造方法,与类同名,没有viod
	Cat(String name,int age){//有参的构造方法,
		this.name=name;
		this.age=age;
		//System.out.println("姓名"+this.name+"年龄"+this.age);
	}
	Cat(){//无参的构造方法,若没有定义构造方法,系统默认创建一个,就是不会执行任何操作
	
	}
	//加viod和返回值都是普通的方法get(),不能被new调用到
	void get(){
		System.out.println(this.name);
	} 
}
public class A6_14{
	public static void main(String[] args){
		Cat one=new Cat();//调用无参的构造方法
		one.get();
		Cat two=new Cat("小花",2);//有参的构造方法,new出来就有小花属性了
		two.get();
	}	
}
/*编译结果:
null
小花

*/

 

A6_15 ~ A6_31 (略!)

 

 

A6_32构造代码块

public class A6_32{
	public static void main(String[] args){
		Person A=new Person();//调用无参构造方法
		Person B=new Person("小李");//调用有参构造方法
		System.out.println(A.country);
		System.out.println(B.country);
		
	}	
}
/*特点:
对象一建立就运行了,而且优先于构造函数执行
作用:给对象进行初始化的
构造代码块和构造方法的区别:
   构造方法是对应的对象进行初始化,
   构造代码块是给所有的对象进行统一的初始化(每个要调用的构造方法,先执行构造代码块)

构造代码块中定义是不同对象共性的初始化内容
*/
class Person{
	String name;
	String country;
	
	Person(){//无参构造方法
		System.out.println("我是无参构造方法");
		
	}
	
	Person(String name){//有参构造方法
		this.name=name;
		
		System.out.println("我是有参构造方法");
	}
	
	//构造代码块,无需调用,直接输出,请看特点,很少用到,面试可能有问道
	{
		country="我是构造代码块";
	}
	
} 

 

 

A6_33构造函数之间的调用

public class A6_33{
	public static void main(String[] args){
		//Student S=new Student("小花",12);
		Student B=new Student("fd");
		
	}	
}
/*
this:看上去,用来区分局部变量和成员变量同名的情况
this:就是代表本类对象,this代表它所在函数(方法)所属对象的引用

构造函数之间的调用只能通过this语句来完成

构造函数之间进行调用时this语句只能出现在第一行,初始化要先执行,如果初始化当中还有初始化,那就去执行更细节的初始化
*/
class Student{
	String name;//成员变量
	int age;
	Student(){
		System.out.println("无参构造方法");
	}
	Student(String name){//局部变量
		this();//调上面的构造方法,
		this.name=name;//有this的是成员变量
		System.out.println("fdfd");
		
	}
	Student(String name,int age){
		this(name);//调上面的构造方法,this相当于new Student(name),即
		this.age=age;//相当于B.age=age
	}		
}

 

 

A6_34 Static关键字

/*
static关键字
作用:是一个修饰符,用于修饰成员(成员变量,成员方法)
1.被static 修饰后的成员变量只有一份(大家共享)
2.当成员被static修饰之后,多了一种访问方式,除了可以对象调用之外,还可以被类直接调用(类名.静态成员)

static的特点:
1.随着类的加载而被加载
2.优先于对象的存在
3.被所有的对象所共享的
4.可以直接被类名所调用

存放位置
类变量随着类的加载而存在于data内存区
实例变量随着对象的建立而存在于堆内存。

生命周期:
1.类变量生命周期最长,随着类的消失而消失
2.实例变量生命比类变量短,它是随着对象的消失而消失

方法注意事项:
1.静态的方法只能访问静态的成员(不能防范局部变量)
2.非静态的方法既能访问静态的成员(成员变量,成员方法)也能访问非静态成员
3.静态的方法中是不可以定义this super关键字
因为静态优先于对象存在,所以静态方法不可以出现this


*/
A6_34
public class A6_34{
	public static void main(String[] args){
		Student A=new Stydent();
		A.country="中国";
		Student B=new Stydent();
		System.out.println(b.country);
		Student.print();
		
	}
}
class Student{
	String name;
	int age;//实例变量
	static String country;//静态变量(类变量),把大家都有的属性单独拿出来,生内存,存放在静态区(data:数据区、共享区、方法区)
	static void print(){
		//String AA=“hello”;//数据局部变量,前面不能加static
		System.out.println(name);
	}
	void p(){
		System.out.println(country);
	}
}

 

 

A6_37 静态的应用范围

/*什么时候使用静态
static所修饰的内容是成员(成员变量,方法)
从两方面入手:
什么时候使用静态的成员变量:
当属于同一个类的所有对象出现共享数据时,
需要将存储这个共享数据的成员变量用static修饰

什么时候使用静态方法
当功能内部没有访问到非静态的成员时(对象特有的数据)
那么该功能可以定义成静态的
*/
public class A6_37{
	public static void main(String[] args){
		Person A=new Person();
		A.name="姚明";
		Person B=new Person();
		B.name="小明"; 
		A.print();
		B.print();
	}
}
class Person{
	String name;//实例成员
	static String country;//静态成员
	void print(){//访问非静态,
		System.out.println(name+"您好");
	}
}


 

 

A6_38 main方法

/*
主函数(主方法)
1.public (访问修饰符,公共的)代表该类或者该函数访问权限是最大的
2.static  代表主函数随着类的加载就已经存在了
3.void    代表主函数没有具体的返回值
4.main    main不是java中的关键字,它是一个特殊的单词,
它能够被JVM(java虚拟机)所识别
5.String[] args 函数的参数,参数类型是一个字符串数组
,该数组的元素是字符串

*/
public class A6_38{
	public static void main(String[] a){
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]);	
		}
	}
}

 

 

A6_39 练习-静态工具类

/*
	静态应用工具类
每一个应用程序都有共性的功能,
可以将这些功能进行抽取,独立封装。以使复用
对象的作用:对象是用来封装数据的,
只要这个类里面有非静态的成员时,
那对象就必须存在。
*/
public class A6_39{
	public static void main(String[] args){
		int[] arr={232,43,535,343,23,43,3,4};
		int[] arr1={34,43,232,34344};
		System.out.println(ArrayOperate.max(arr));
	}
}

 

 

A6_42 静态代码块

/*
静态代码块
格式:
static{
	静态代码块中执行语句	
}
特点:随着类的加载而执行,并且只会执行一次,并且还优先于主函数。
作用:用于给类进行初始化(构造代码块是给成员初始化)
*/
class Person{
	static{
		System.out.println("我是静态代码块");
	}
	{
		System.out.println("我是构造代码块");
	}
}
class A6_42{
	public static void main(String[] args){
		Person n= new Person();
		Person m= new Person();
	}
}

 

 

A6_43 对象初始化过程

class Student{
	static{
		System.out.println("我是静态代码块");
	}
	{
		System.out.println("我是构造代码块");
	}
	void print(){
		System.out.println("我是普通方法");
	}
	private String name;
	private static String country;
}
public class A6_43{
	public static void main(String[] args){
		Student s=new Student();
	}
}
/*
1.因为new Student()用到了Student类,所以会把它从硬盘上加载进入内存
2.如果有static静态代码块就会随着类的加载而执行,
还有静态成员和普通方法也会随着类的加载而被加载
3.在堆中开辟空间,分配内存地址
4.在堆中建立对象特有属性,并同时对特有属性进行默认初始化
5.对属性进行显示初始化
6.执行构造代码块。对所有对象进行初始化
7.执行对应的构造函数,对对象进行初始化.
8.将内存地址给S(给栈中的变量)
*/

 

 

A6_44单例设计模式

/*
设计模式:针对此类问题最有效的解决方法
java23种设计模式
单例设计模式:解决一个类只在内存中存在一个对象

如何让一个类在内存中只存在一个对象?
1.禁止其他的应用程序,通过此类来创建对象
2.既然外部不能通过此类创建对象了,我们要用对象,
就可以再本类里面创建本类对象。
3.为了其他应用程序能够访问到本类里面创建的对象,
我需要对外界提供一种访问方式

如何用代码体现出来:
1.私有化构造方法
2.在本类中创建本类对象
3.对外界提供访问的方法
*/
class Person{
	String name;
	private Person(){}
	static Person p=new Person();//下面的事静态static
	public static Person getInstance(){//静态要调用,所有必须为静态
		return p;//这个get是静态,返回p也是静态
	}
}
public class A6_44{
	public static void main(String[] args){//静态
		Person A=Person.getInstance();//调用静态,静态只能调用静态,
		A.name="小明";
		Person B=Person.getInstance();
		System.out.println(B.name);//输出小明,说明和A调用同一个对象
	}
}
/*输出结果:
小明
*/

 

 

A6_45继承1

/*
	继承
继承的概述:
1.提高了代码复用性,简化了代码
2.让类与类之间产生了继承关系,才有了后面的多态特性的存在
注意:千万不要为了获取其他类的功能简化代码,而建立继承关系,
必须要类与类之间存在继承关系, 继承关系:is a
*/
//父类,超类,基类

//子类,导出类
Person{
	String name;
	int age;
}
class Student extends Person{
	void study(){
		System.out.println("学习");
	}
}
class Teather extends Person{
	void teath(){
		System.out.println("教书");
	}
}

 

 

A6_46继承2

/*
继承概述_2
子类拥有父类的成员,子类不能拥有父类中被private修饰后的成员

java多层继承 在多层继承中最下层的子类拥有整个继承体系的成员,
最上层的父类里面定义所有子类的共性描述

java中不支持多继承,只支持单继承。因为多继承存在安全隐患,
当多个父类定义了相同的成员,子类对象不确定运行哪一个。
java保留这种机制,并用了另一方式来体现 多实现(如接口)
*/
class A{
	String name;
	void show(){
	
	}
}
class B{
	int age;
	void show(){
	
	}
}
class C extends A{//不支持多继承

}

class D extends C{//D有C的属性,同时也有A的属性
	
	
}

class A6_46{
	public static void main(String[] args){
		C c=new C();
		c.show();
	}
}

 

 

A6_47 子父类中的成员变量

/*子父类成员特点
成员:
1.成员变量
2.函数
3.构造函数

变量:
this 代表当前对象的引用 this.变量  首先在本类中找所需要的这个变量,
如果没有找到再父类中找。
super 用于访问当前对象的父类成员,super.变量 直接父类中找所需变量
*/

class Person{//父类
	String name="张三";
}
class Student extends Person{//子类,继承父类
	String name="李四";
	void show(){
		System.out.println(super.name);//super先去父类找,要是用this先在本类找(输出李四)
	}
}
public class A6_47{
	public static void main(String[] args){
		Student stu=new Student();
		stu.show();//调用shoe()方法
	}
}
/*输出结果
张三
*/

 

 

A6_48子父类中的函数

/*
动物
猫,狗

当子类中出现和父类中一样的函数时,当子类对象调用该函数,
运行的是子类中的函数,如同父类中的函数被覆盖了一样,
这种情况就是函数的另一种特性:重写(覆盖)

注意:
1.子类覆盖父类时,必须要保证子类权限大于等于父类,才可以覆盖,否则编译出错

访问权限修饰符:public> default>private   成员前面没加任何访问权限
修饰符默认权限就是default

2.静态的函数只能覆盖静态的

记住:
重载:只看同名的方法的参数列表,如,父类是run()方法、子类是run(String a),存在的参数不同,方法名都一样
重写:子父类方法要一模一样,如都是run()方法,方法名参数都一样

*/

class Animal{//父类 
	String Type;
	public void run(){//不写public就默认default,现在是public
		System.out.println("跑步中");
	}	
}
class Cat extends Animal{
	
} 
class Dog extends Animal{ 
    //String Type="大黄狗";//不加String说明要用父类的Type,这样会报错,加String是重新定义Type
	public void run(String a){//要加public,否则权限比父类方法小,就不能重写(覆盖),现在public等于父类的,可以覆盖
		Type="大黄狗";//要写在run()方法中,因为这个Type是Animal中的变量,写在外面是重新定义
		System.out.println(Type+"哼着歌跑步中");//因为这个类不想用父类的方法,所有需要重写,如:狗不想这样跑步,要哼着歌
		
	}
	
}
public class A6_48{
	public static void main(String[] args){
		Cat C=new Cat();
		C.run();
		Dog d=new Dog();
		d.run();
		d.run("dd");
	}
}

 

 

 

A6_49继承中的构造函数

/*
有了子父类之后构造函数的特点:
在对子类对象进行初始化的时候,
父类的构造方法也会运行,那是因为子类的构造函数默认
第一行
有一条隐式的语句 super();每个子类构造方法都有

子类每个构造方法第一行都有一个隐式的 super();
*/
class fu{//父类
	String name;
	fu(){//无参
		System.out.println("父类构造方法");
	}
	fu(String n){//有参
		this.name=n;
		System.out.println("父类有参构造方法");
	}
}
class zi extends fu{//子类
	zi(){//无参
		//super();//不写也会默认有这个,所有先访问父类
		System.out.println("子类构造方法");	
	}
	zi(String n){//有参
		//super();//构造方法的第一句不写也会默认有这个,所有先访问父类,
		          //注意这个super()是无参,所以访问的事父类的无参构造方法
		         //要调用父类的有参构造方法,那就用super(“小李”);
				 
		this.name="小李";
		//super();不能写在这个位置,会报错,只能在构造方法的第一句
		System.out.println("子类有参构造方法");	
	}
}
public class A6_49{
	public static void main(String[] args){
		zi z=new zi("小李");//调用子类有参的构造方法
	}
}

/*输出结果:
父类构造方法
子类有参构造方法

*/

 

 

 

A6_50对象转型

/*
对象的转型:
1.对象的向上转型 子类转成父类 默认进行 父类引用指向子类对象
2.对象的向下转型 父类转成子类 强制进行 如:Cat c=(cat)a

关键字:instanceof 测试左边的对象是否是右边类的实例 
如果是返回true 不是返回false
*/ 

class Animal{//父类,动物
	void sleep(){
		System.out.println("睡觉中");
	}	
}
class Cat extends Animal{//子类,猫
	void catchMouse(){
		System.out.println("捕鼠");
	}
}
class Dog extends Animal{//子类,狗
		
}
public class A6_50{
	public static void main(String[] args){
		Cat a=new Cat();
		System.out.println(a instanceof Cat);//输出为trun,
		System.out.println(a instanceof Dog);//会报错,猫和狗它们没有关系,只能和Animal有关系
		
		Animal a=new Cat();//向上转型,
		System.out.println(a instanceof Cat);//输出为trun,猫是动物是实例(上面是cat()赋予了a)
		
		Animal a=new Animal();
		System.out.println(a instanceof Cat);//输出为false,动物不能说是猫,有可能是狗
		System.out.println(a instanceof Dog);//输出为false,同理
		
		
		/*向上转型和向下转型的区别*/
		Animal a=new Cat();//向上转型,a是猫,当做动物看待
		a.sleep();//可以,猫看成动物,所有能访问父类
		a.catchMouse();//不可以,a已经当做动物看了,动物不能看成猫,不能访问子类(猫)独有的方法
		Dog d = (Dog)a//a是猫,编译不会报错,运行就会报错,因为a猫的类型不能给b狗
		
		Cat c=(cat)a;//向下转型,a是当做动物看待(父类),要当做猫看(即待转成子类),
		c.catchMouse();//能访问父类
		c.sleep();//也能访问子类
		
		
		
	}
}

 

 

 

A6_51多态的概述

/*
OOP三大特性:封装,继承,多态
多态:可以理解为事物存在的多种体现形态
动物:猫,  狗, 猪 (猫是动物,动物也有猫)
人:  男人  女人 (一个男人我可以称之为人,一个女人我也可以称之为人)

1.多态的体现
父类引用指向子类对象

2.多态的前提
(1)必须得类与类之间存在关系,可以是继承关系 也可以是实现关系
(2)必须得有重写 //要是Dog没有重写,编译不会报错,因为Dog也会访问Animal,此时多态没有意义

3.多态的好处
大大提高了程序的可扩展性(不做很大的修改就多很多功能)

4.多态的弊端
提高的程序可扩展性,只能用父类的引用,访问到父类中成员(向上转型:缺点是只能看到Animal里面共性的,看不到其他的)
多态成员变量的特点:
1.编译期间:参阅的是引用型变量所属的类中是否有调用的方法
2.运行期间:参阅对象所属的类中是否有调用的方法
*/
class Animal{
	/*要是没有这个。下面的function(Animal c)会报错
	 void sing(){
		System.out.println("唱歌");
	 }
	*/
}
class Dog extends Animal{
	void sing(){//重写
		System.out.println("汪汪的唱歌");//对动物唱歌不满意,所以要重写汪汪的唱歌
	}
}
class Cat extends Animal{
	void sing(){
		System.out.println("喵喵的唱歌");//同理重写
	}
	void catchMouse(){
		System.out.println("捕鼠");
	}
}


public class A6_51{
	public static void main(String[] args){
		
		Cat c=new Cat();
		function(c);
		Dog d=new Dog();
		function(d);
		Pig p=new Pig();
		function(p);
		//可以继续接着来几种动物都可以,不用每个动物都写 function,用function(Animal c)即可
	}
	
	/**每个动物要唱下歌,都要对应写多个封装,太麻烦,所以不用
	public static void function(Cat c){//封装
	    
		c.sing();
		
	 }
	public static void function(Dog d){//封装
	    
		d.sing();
		
	 }
	*/
	
	 //要是Dog没有重写,编译不会报错,因为Dog也会访问Animal,此时多态没有意义
	public static void function(Animal c){//封装,把c自己看成动物,其他动物可以访问
		//Animal c=new Cat();//A——50对象转型章节:向上转型,主要访问共性(父类)内容,向下转型,父类子类都可以访问
		
		Cat c1=(Cat)c;//需要向下转型
		c1.catchMouse();//向上转型,只能看到父类的成员,单写这个会报错,所以需要上面的转型
	}
}


 

 

 

 

A6_51多态的概述_1

/*
OOP三大特性:封装,继承,多态
多态:可以理解为事物存在的多种体现形态
动物:猫,  狗, 猪 (猫是动物,动物也有猫)
人:  男人  女人 (一个男人我可以称之为人,一个女人我也可以称之为人)

1.多态的体现
父类引用指向子类对象

2.多态的前提
(1)必须得类与类之间存在关系,可以是继承关系 也可以是实现关系
(2)必须得有重写 //要是Dog没有重写,编译不会报错,因为Dog也会访问Animal,此时多态没有意义

3.多态的好处
大大提高了程序的可扩展性(不做很大的修改就多很多功能)

4.多态的弊端
提高的程序可扩展性,只能用父类的引用,访问到父类中成员(向上转型:缺点是只能看到Animal里面共性的,看不到其他的)
多态成员变量的特点:
1.编译期间:参阅的是引用型变量所属的类中是否有调用的方法
2.运行期间:参阅对象所属的类中是否有调用的方法
*/
class Animal{
	/*要是没有这个。下面的function(Animal c)会报错
	 void sing(){
		System.out.println("唱歌");
	 }
	*/
}
class Dog extends Animal{
	void sing(){//重写
		System.out.println("汪汪的唱歌");//对动物唱歌不满意,所以要重写汪汪的唱歌
	}
}
class Cat extends Animal{
	void sing(){
		System.out.println("喵喵的唱歌");//同理重写
	}
	void catchMouse(){
		System.out.println("捕鼠");
	}
}


public class A6_51{
	public static void main(String[] args){
		
		Cat c=new Cat();
		function(c);
		Dog d=new Dog();
		function(d);
		Pig p=new Pig();
		function(p);
		//可以继续接着来几种动物都可以,不用每个动物都写 function,用function(Animal c)即可
	}
	
	/**每个动物要唱下歌,都要对应写多个封装,太麻烦,所以不用
	public static void function(Cat c){//封装
	    
		c.sing();
		
	 }
	public static void function(Dog d){//封装
	    
		d.sing();
		
	 }
	*/
	
	 //要是Dog没有重写,编译不会报错,因为Dog也会访问Animal,此时多态没有意义
	public static void function(Animal c){//封装,把c自己看成动物,其他动物可以访问
		//Animal c=new Cat();//A——50对象转型章节:向上转型,主要访问共性(父类)内容,向下转型,父类子类都可以访问
		
		Cat c1=(Cat)c;//需要向下转型
		c1.catchMouse();//向上转型,只能看到父类的成员,单写这个会报错,所以需要上面的转型
	}
}

 

 

 

A6_53多态的练习

/*俄罗斯方块,每种都有好几个形状再变化,如长字型有:横、竖*/

import java.util.Random;//随机数,随机变化

//定义方块的类型:山字型、L字型、Z字型、长字型、田字型

class FK{//方块父类
	void bx(){
		System.out.println("变形");
	}
}
class FK_szx extends FK{//山字型
	void bx(){//变形方式不满意,在重写
		System.out.println("山字型在变形");
	}
}
class FK_lzx extends FK {//L字型
	void bx(){//同理,重写
		System.out.println("L字型在变形");
	}
}
class FK_zzx extends FK{//Z字型
	void bx(){//同理,重写
		System.out.println("Z字型在变形");
	}
}
class FK_cfx extends FK{//长方型
	void bx(){//同理,重写
		System.out.println("长方型在变形");
	}
}
class FK_tzx extends FK{//田字型
	void bx(){//同理,重写
		System.out.println("田字型在变形");
	}
}

//有继承,有重写,有父类指向子类的对象(都有父类的共性),所以用多态,这些都是前提
class A6_53{
	public static void main(String[] args){
		Random r=new Random();//随机数对象
		int a=r.nextInt(5);//产生一个随机数用a接收下
		FK fk=null;//用多态方法,父类,没有指向任何对象
		switch(a){
		case 0://随机数为0,以下同理
		    /*非多态的写法(下同),代码好多看起来都一样,所以用多态优化以下
			FK_szx szx=new FK_szx();
			szx.bx();//每次调用变形的方法(父类)都一样,所以用多态方法改写
			break;
			*/
			fk=new FK_szx();//产生山字型形状赋给了父类fk,fk父类指向子类FK_szx的对象,以下同理
			break;
			
		case 1:
			/*非多态的写法(下同)
			FK_lzx lzx=new FK_lzx();
			lzx.bx();
			break;
			*/
			fk=new FK_lzx();
			break;
			
		case 2:
			/*非多态的写法(下同)
			FK_zzx zzx=new FK_zzx();
			zzx.bx();
			break;
			*/
			fk=new FK_zzx();
			break;
			
		case 3:
			/*非多态的写法(下同)
			FK_cfx cfx=new FK_cfx();
			cfx.bx();
			break;
			*/
			fk=new FK_cfx();
			break;
			
		case 4:
			/*非多态的写法(下同)
			FK_tzx tzx=new FK_tzx();
			tzx.bx();
			break;
			*/
			fk=new FK_tzx();
			break;
		//****再多都可以写,不用太大改动*****提高程序的可扩展性
		}
		
		/*
		通俗理解:动物园管理员叫动物来吃饭,至少动物具备吃饭的行为(否则无意义),
		跑过来一只猫就按照猫的吃法(猫怎么吃它就怎么吃),跑过来一只狗就按照狗的吃法(狗怎么吃它就怎么吃)
		*/
		
		fk.bx();//父类指向哪个就用哪个,通用都有bx()变形的方法
	}
}



 

 

 

A6_54 匿名对象

/*
匿名对象:没有名字的对象
匿名对象的使用方式之一:当对对象的方法只调用一次时,我们可以用匿名对象来完成
,比较简化。
匿名对象的使用方式之二:匿名对象可以被当做实参传递
*/
class Car{
	String color;
	void start(){
		System.out.println("汽车被开动");
	}
	
}
public class A6_54{
	public static void main(String[] args){
		// Car c=new Car(); 一般的做法,把地址转给c
		//new Car().start();这个就是匿名对象,不转地址
		//new Car().color=“蓝色”;改变属性值这个没有意义,因为不只调用一次
		
		print(new Car());//匿名对象调用有参方法,简写
		/*相当于
		Car c=new Car();
		print(c);
		*/
	}
	static void print(Car c){//有参
		
		c.start();//被调用
	}
}

 

 

 

A6_55Object类toString()

/*
一个特殊的类
Object:它是java中所有对象的直接或者间接父类,根父类(基类),
它里面定义的功能时所有对象都应该具备的

Object的类有哪些在API里面找(JAVAAPI.CHM文本网上有下载)

记住:当定义一个新类时,没有指明要继承某类,它默认继承Object类

*/
class Animal{//也默认继承Object类
	
	
}
class Cat{//没有指明要继承的父类,默认继承Object类,
//要是写了extends Animal,就不会继承Object类,也会有toString,因为继承的Animal父类也默认继承Object,里面含有toString
	public String toString(){//不写也会默认有,根据查询API方法名也是这样,所以可以重写toString()
		return "你好";//重写了
	}
}

class A6_55{
	public static void main(String[] args){
		/*cat中要是没有toString()
		Cat c=new Cat();
		System.out.println(c);//输出一个地址,因为Cat类会默认有toString()方法
		相当于System.out.println(c.toString());
		*/
		System.out.println(new Cat().toString());//相当于上面的注释
	}
}

 

 

A6_56Object类equals()

/*
一个特殊的类
Object:它是java中所有对象的直接或者间接父类,根父类(基类),
它里面定义的功能时所有对象都应该具备的

记住:当定义一个新类时,没有指明要继承某类,它默认继承Object类

==和Object里面的equals其实比较的就两对象的内存地址是否一致

Object类equals()是比较两个对象是否相等
*/
class Cat{
	int num;
	//Object本身就有了比对的方法了,所以就用equals()
	public boolean equals(Object fff){//Object ff=new Cat();向上转型
		if(fff instanceof Cat){//instanceof判断,是不是猫,否则C2是狗,编译会报错
			Cat ee =(Cat) fff;//向下转型,是猫就转型
			return	this.num==ee.num;//this相当于当前对象的引用
		}else{
			return false;//猫和狗本来就不匹配,所以返回false
		}
		
	}
}
class Dog{

}
public class A6_56{
	public static void main(String[] args){
		Cat c = new Cat();//C是猫
		Dog C2 = new Dog();//C2是狗
		System.out.println(c.equals(c2));
		//System.out.println("ff".equals("ff"));//ff是对象,可以直接调用方法,equals相当于被重写过的
	}
}

 

 

 

A6_57 final关键字

/*
final(最终)是一个修饰符
1.final可以修饰类,函数,变量(成员变量,局部变量)

2.被final修饰后的类不可以被其他类继承
  如: 
    final class Person{}//final修饰
	clsaa Student extends Person(){}//编译报错,Person已经被final修饰
	
3.被final修饰后的函数不可以被重写
  如:
    class Person{
		final void show(){//final修饰
			System.out.println("你好")
			};
	}
	clsaa Student extends Person(){//Person没有被final修饰,这个可以继承
		void show(){//不能重写,因为show()方法被final修饰
			System.out.println("世界")
			};
	}

4.被final修饰后的变量不允许被再次赋值,final在对变量进行修饰时一定赋值,
   如:
     final int a=34
     a=52;//报错,不能被重写赋值
	 
5.被final修饰后的变量我们称它常量,常量不能被改变

6.被public final static 多个修饰符修饰的变量我们称它为:全局常量,
    如:
	  public final static String STUDENT_NAME="小李";


注意:常量的命名规范:字母全部要大写,如:final String NAME=“小王”;
如果这个名字是由多个单词组成,在单词之间用_隔开,如:final String STUDENT_NAME="小李";
*/

class Student{
	public final static String STUDENT_NAME="小李";//全局常量,被final修饰后都是常量
}
public class A6_57{
	public static void main(String[] args){
		Student s=new Student();//输出被final修饰的值
		Student s1=new Student();//和上一个一样的值,浪费空间,没必要
	}
}

 

 

 

A6_58 抽象类

/*
abstract:是一个修饰符
可以修饰方法,类
1.当我们多个类存在相同的功能,但是功能的主体不同,这时我进行向上抽取
只抽取功能的定义不抽取功能的主体

抽象类的特点:
1.抽象方法一定要在抽象类中
2.抽象类和抽象方法必须要被abstract关键字修饰
  abstract只能修饰类和函数
3.抽象的类是不能被创建对象,因为调用抽象的方法没意义
4.抽象类的中方法要被使用,必须由子类重写抽象类中的方法
,然后创建子类对象来调用
5.抽象类中可以定义非抽象的方法,有时我们需要此类不能被new关键字创建对象时,
可以用abstract将此类变成抽象类。
6.子类如果只重写一部分的抽象方法,那么该子类还是一个抽象类,如果抽象类的方法
要被使用,子类必须重写抽象类中的所有方法。

值得注意:抽象类和普通的类没有太大的不同。
1.抽象类无法同过new关键字创建对象
2.抽象类里面可有抽象的方法


*/
abstract class Animal{//抽象类,不能new对象来调,如不能:Animal t=new Animal();,但是可以supe创建对象
	abstract void sing();//方法少了大括号,大括号内容都被重写了,留着没有意义void sing();就这么写,看到不懂得方法就用加abstract,
	abstract void show();
}
class Cat extends Animal{
	void sing(){
		System.out.println("喵喵唱歌");
	}
	void show(){//猫类重写了,狗类等其他的子类也要重写
	
	}
}
class Dog extends Animal{
	void sing(){
		System.out.println("汪汪唱歌");
	}
	void show(){//统一都要重写
	
	}
}
public class A6_58{
	public static void main(String[] args){
		Animal t=new Cat();//多态,向上转型,可以接受
		t.sing();
	}
}

A6_60模板方法设计模式

/*
需求:求一段代码运行所花费时间
原理:结束时间-开始时间 System.currentTimeMillis()
什么是模板方法设计模式?
定义功能时,功能的一部分是确定(印章是模板),而确定的部分在使用不确定(用什么颜色的墨水),
那么这时就得将不确定的部分暴露出去,由该子类去完成。
举例:造冰激凌的机器就是模板,这是确定的,造多大。不确定的是你给我什么材料,什么奶油我就造什么味的


*/

//编译生成class发给用户,用户自己写段代码,利用你的方法测用户自己写的代码运行所花的时间,不能写死
abstract class Demo{//对应下面的抽象abstract,一个类出现了抽象的方法,那个类也要变成抽象
	public final void getTime(){//final防止被覆盖,因为用户不一定知道
		long start =System.currentTimeMillis();//1秒=1000毫秒
		function();	//默认this.function();子类对象就是当前对象	这里相当于把Test类方法写在这里,也就是要运行的代码,要是写在这里就是写死了
		long stop =System.currentTimeMillis();
		System.out.println("共花费了"+(stop-start));
	} 
	public abstract void function();//不确定你要对哪些代码所花费的时间,所以要补写public void function(){}就变成空的方法无意义,就变成抽象的方法
}
//这块是用户自己重写,其他的目的是测这块代码所花费的时间
class Test extends Demo{//子类对象
	public void function(){//Test类方法
		for(int i=0;i<1000;i++){//为了效果更明显,用for循环
			System.out.print("f");//求这段代码运行所花费的时间,输出1000个f
		}
	}
}
public class A6_60{
	public static void main(String[] args){//静态方法可以通过类名来访问
		Test t=new Test();
		t.getTime();
	}
}

 

 

 

A6_61接口(一)

/*
接口:初步理解,接口是一个特殊的抽象类,当抽象类中全部是抽象方法时,
可以通过接口的形式来体现。
class 用于定义类
interface 用于定义接口

接口中成员的格式:
1.public static final String NAME="小李";//全局常量,public static final这三个修饰符位置可以随便放
2.public abstract void show(); //抽象方法

注意:
1.接口中只能出现public 访问修饰符,(不能加其他,如:private,会报错的)
2.接口不可以创建对象,因为里面有抽象方法,需要被子类实现(接口叫实现,不叫重写),子类对接口中的所有抽象方法实现后,子类才能够实例化,否则子类就是一个抽象类
*/
interface smoket{//接口
	public static final String NAME="小李";//接口中三个修饰符不写也会默认加,接口中没有成员变量
	//int a = 0;默认会加上public static final这些修饰符,所以属于全局常量,不是成员变量
	public abstract void show();//public、abstract不写会默认加的
	//接口没有构造方法/函数,抽象类有构造方法/函数(不能通过new关键字来创建对象),
}
class Student implements smoket{//类之间是继承关系,接口是实现关系,把接口的抽象方法要实现
	public void show(){//类似重写的方法,不写abstract,
		System.out.println("在吸烟");
	}
}
public class A6_61{
	public static void main(String[] args){
		Student s=new Student();
		s.show();	
	}
}

 

 

 

A6_62接口(二)

/*
java不支持多继承,因为存在安全隐患,当父类中定义了相同功能,
功能内容不同时,子类不确定要运行哪一个
但是java保留了这种机制,并用另一种体现形式来完成表示>>多实现

一个类可以实现多个接口(java虽不支持多继承,但也以另一种形式保留了,接口)

关系:
类与类之间:继承关系extends
接口与类之间:实现关系implements
接口与接口之间:继承关系extends
*/
interface Smoket{//接口
	public abstract void smoket();//是public
}
interface Game extends Smoket{//接口与接口之间:继承关系
	public abstract void computerGame();//要被重写
}
class Student implements Smoket,Game{//接口与类之间:实现关系,多接口之间要逗号隔开
	public void smoket(){//不写public,因为接口中是public不能低于
		System.out.println("吸烟");
	}
	public void computerGame(){//要重写,不然要报错
		System.out.println("游戏");
	}
} 
public class A6_62{
	public static void main(String[] args){
		/*
		Student s=new Student();
		s.smoket();
		s.computerGame()
		*/
	}
}

 

 

 

A6_63接口练习

/*
通俗理解:以前的电脑主板和CPU是焊接在一起,要是不满意CPU就连主板一起换掉,现在技术先进了,主板和CPU提供接口,可以单独换CPU即可。

接口和多态两者的区别:

接口:提高了我们功能的扩展性  ,
通俗理解:电脑没有USB接口是可以的,还可以运行,但是就不能扩展硬盘,要换原装硬盘,装新的,旧的要丢掉
因为它降低事物与事物之间的耦合性(关系紧密程度,就是焊接在一起,谁也不能拆散我们)
通俗理解:有什么好处,就是共同开发,你要等我开发玩你才能开始,接口就可以分开做,后面再通过接口

多态:提供我们的程序的扩展性;



父类中定义的是多个类中共性的基本功能
接口中定义的是扩展功能

接口好处:
可以多实现,也就是一个类可以实现多个接口


*/
class Person{//父类中定义的是多个类中共性的基本功能,不能少
	String name;
	int age;
}
interface Smoket{//接口中定义的是扩展功能,可以不要
	public abstract void smoket();
}
class Student extends Person{

}
class Worker extends Person implements Smoket{
	public void smoket(){
		System.out.print("抽烟");
	}	
}
public class A6_63{
	public static void main(String[] args){
		Worker w=new Worker();
		w.smoket();
	}
}

 

 

 

A6_64 包

/*
包(package)
什么是包呢?可以理解为文件夹
包的作用:
1.对类进行分类管理
2.给类提供了多层命名空间


注意:
1.类名的全称是包名.类名
2.定义包的语句一定要在代码的第一行


*/
package pack;
public class A6_64{
	public static void main(String[] args){
		System.out.println("你好");
	}
}

 

 

 

 

---------------------------------完,不明白的给我留言·······················

 

 

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测试狂人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值