面向对象
类public class 类名{数据类型 变量1 方法 }
类 成员变量 成员方法
对象 创建对象 使用对象 使用方法
成员变量和局部变量
-
静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭。
非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例(new)来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。 -
在内存中存储位置
静态方法和静态变量创建后始终使用同一块内存,是连续的。
非静态方法会存在于内存的多个地方,是离散的。 -
效率
静态方法的使用效率比非静态方法的效率高。 -
线程安全
静态方法是共享代码段,静态变量是共享数据段。既然是“共享”就有并发(Concurrence)的问题。
非静态方法是针对确定的一个对象的,所以不会存在线程安全的问题。 -
静态方法和非静态方法的区别:
1、静态方法属于类所有,类实例化前即可使用;
2、非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员;
3、因为静态方法在类实例化前就可以使用,而类中的非静态变量必须在实例化之后才能分配内存;
4、static内部只能出现static变量和其他static方法!而且static方法中还不能使用this等关键字,因为它是属于整个类;
5、静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁;
6、静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存。
主要区别:静态方法在创建对象前就可以使用了,非静态方法必须通过new出来的对象调用。 -
使用范围
静态方法:⒈ 有静态属性的类,一般会定义静态方法。⒉ 没有属性的类,一般会定义静态方法。⒊ 如果一个方法与他所在类的实例对象无关,那么它就应该是静态的。
静态方法可以被继承但是不能被覆盖。 -
总计
如果静态方法在系统中定义太多,会占用大量的资源,最后造成内存溢出,所以静态方法不能滥用。如果从线程安全、性能、兼容性上来看,选用实例化方法为宜。 -
new关键字, 是指告诉JVM , 需要明确的去创建一个新的对象 , 去开辟一块新的堆内存空间.
-
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。 不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐式的。
匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6、只能访问final型的局部变量。JDK1.8之后变量默认为final类型,但是只要第二次赋值,就不再是final类型的了。
只能访问final类型的局部变量的原因,因为局部类编译的时候是单独编译成一个文件,所以在文件中有final变量的备份。
静态内部类是不需要依赖于外部类对象的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法。
Number:Integer、Short、Long、Double、Float、Byte都是Number的子类表示是一个数字。
**Object:**Character、Boolean都是Object的直接子类。基本数据类型和包装类型的区别
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是
2、包装类型是引用的传递,基本类型是值的传递
3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间
4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们
5、初始值不同: int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为null
6、使用方式不同,基本数据类型直接赋值使用就好 ,而包装类型是在集合如 coolection Map时会使用只声明而未实现的方法称为抽象方法(未实现指的是:没有“{}”方法体),抽象方法必须使用abstract关键字声明。
抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成。 不能被我们创建,但是jvm虚拟器可以创建。
一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须覆写(重写)抽象类中的全部抽象方法。
因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能
抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。 默认缺省为 public
1、抽象类要被子类继承,接口要被类实现。
2、接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法。
3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
4、抽象类使用继承来使用, 无法多继承。 接口使用实现来使用, 可以多实现
5、抽象类中可以包含static方法 ,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明静态方法)
6、接口不能有构造方法,但是抽象类可以有
7、1.8后接口允许出现有方法体的方法
方法的重载 和 重写 也是多态的一种
-
**==**是一个比较运算符,基本数据类型比较的是值,引用数据类型比较的是地址值。(比较地址值即是指是否为同一个对象的引用)
**equals()**是一个方法,只能比较引用数据类型。重写前比较的是地址值,重写后比一般是比较对象的属性。
构造方法:方法名称必须与类名相同(重载), 没有返回值类型的声明,造方法中没有任何的代码。
static:静态成员 在类加载时加载并初始化
全局常量:(public static final)可以在任何位置被访问。
final:
类文件
public class student { //类
//成员变量 在方法外的变量 堆内存 有默认初始化值
String name;
int age;
//成员方法 在方法内的变量为局部变量 栈内存 无初始化值 要先赋值
public void study(){
System.out.println("好好学习");
}
public void homework(){
System.out.println("多做练习");
}
}
对象文件
public class studentDeom {
public static void main(String[] args) {
//创建对象
student s1=new student();
//使用对象
System.out.println(s1.name+","+s1.age);
s1.name="1";
s1.age=19;
System.out.println(s1.name+","+s1.age);
//使用方法
s1.study();
s1.homework();
//创建多个对象 地址相同 可直接指向同一个
student s2=s1; // student s2=new student();
//使用对象
s2.name="2";
s2.age=18;
System.out.println(s2.name+","+s2.age);
//使用方法
s1.study();
s1.homework();
}
}
private 权限修饰符
可以修饰成员(变量和方法) 保护成员不被别的类使用
被private修饰的成员只在本类才能被访问
使用setXxx/getXxx方法
set是为对象中的属性赋值 get是从对象中获取属性值
this修饰的变量 指代成员变量(当成员变量与局部变量同名时)
封装 不允许外部程序直接访问 private 使用 get/set方法访问
类文件
public class student { //类
//成员变量
String name;
//使用private修饰
private int age;
//成员方法 提供get/set方法
public void setAge(int age){
//age=a;
if (a<0||a>120){
System.out.println("你给的年龄有误");
}
else {
this.age=age;
}
}
public int getAge(){
return age;
}
public void show(){
System.out.println(name+","+age);
}
}
对象文件
public class studentDeom {
public static void main(String[] args) {
//创建对象
student s1=new student();
//s1.age=19; 已被private修饰,不能使用
//使用方法
s1.setAge(19);
s1.show();
//创建多个对象 地址相同 可直接指向同一个
student s2=s1; // student s2=new student();
//使用方法
s2.setAge(18);
s2.show();
}
}
构造方法 用于创建对象 public class 类名{修饰符 类名(参数){} } 类似函数
人工定义构造方法 将不再给默认无参构造方法 建议手动给
类
public class student1 {
private String name;
private int age;
//构造方法
public student1(){}// 给无参构造方法
public student1(String name,int age){
this.name=name;
this.age=age;
}
//成员方法
public void show(){
System.out.println(name+","+age);
}
}
对象
public class studentDeom1 {
public static void main(String[] args) {
student1 s3=new student1("3",20);
s3.show();
}
}
完整案例
类文件
public class student2 {
private String name;
private int age;
//构造方法
public student2(){} //给无参构造方法
public student2(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name) {
this.name = name;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
public void show(){
System.out.println(name+","+age);
}
}
对象文件
public class studentDeom2 {
public static void main(String[] args) {
//无参构造方法创建
student2 s1=new student2();
s1.setName("1");
s1.setAge(18);
s1.show();
//构造方法
student2 s2=new student2("2",19);
s2.show();
}
}
用户登录
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//使用String构造字符
String user = "1";
String pass = "2260688132";
//for循环给3次机会
for (int i = 0; i < 3; i++) {
System.out.println("请输入用户名");
String name = sc.nextLine(); //字符串使用nextLine
System.out.println("请输入密码");
String pwd = sc.nextLine();
//使用equals()比较name和user pwd和pass
if (name.equals(user) && pwd.equals(pass)) {
System.out.println("登陆成功");
break; //密码正确 结束循环
}else if(2-i==0){
System.out.println("用户名或密码错误,你的账户已被锁定");
}
else {
System.out.println("用户名或密码错误"+"你还有"+(2-i)+"机会");
}
}
}
遍历字符串
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串");
String line=sc.nextLine();
for (int i=0;i<line.length();i++){
System.out.println(line.charAt(i));//字符串输出格式
}
}
统计字符串中的各字符次数
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串");
String line=sc.nextLine();
int bigcount=0;
int smallcount=0;
int numbercount=0;
for (int i=0;i<line.length();i++){
char ch=line.charAt(i); //获取第line中第i个字符
if (ch>='A' && ch<='Z'){
bigcount++;
}
if (ch>='a' && ch<='z'){
smallcount++;
}
if (ch>='0' && ch<='9'){
numbercount++;
}
}
System.out.println("大写字母:"+bigcount);
System.out.println("小写字母:"+smallcount);
System.out.println("数字:"+numbercount);
}
字符串反转
System.out.println("请输入字符串");
String s=sc.nextLine();
s=re(s);
System.out.println(s);
public static String re(String s){
String ss="";
for (int i=s.length()-1;i>=0;i--){
//s.lenth()为字符串长度
ss+=s.charAt(i); //返回指定位置的char值
}
return ss;
}
String str = "123abc";
char[] arr = str.toCharArray();
for (char s:arr){
System.out.println(s);
}
StringBuilder 可变的字符串
public StringBuilder() 创建一个空白可变的字符串对象
public StringBuilder(String str)根据字符串内容,创建可变字符串对象
capacity()返回当前容量
StringBuilder sb=new StringBuilder();
//链式编程
sb.append("hello").append("world").append("java");
System.out.println(sb);
//字符串反转
sb.reverse();
System.out.println(sb);
//StringBuilder与String转换
String s1=sb.toString(); //SB转S
System.out.println(s1);
StringBuilder sb1=new StringBuilder(s1);//S转SB
System.out.println(sb1);
字符串拼接
int[] arr={1,2,3};
String s2=array(arr);
System.out.println(s2);
public static String array(int[] arr){
StringBuilder sb2=new StringBuilder();
for (int i=0;i<arr.length;i++){
if (i==arr.length-1){
sb2.append(arr[i]);
}else {
sb2.append(arr[i]).append(",");
}
}
String s2=sb2.toString();
return s2;
}
字符串反转
System.out.println("请输入字符串");
String s=sc.nextLine();
s=re(s);
System.out.println(s);
public static String re(String s){
StringBuilder sb4=new StringBuilder(s);
sb4.reverse();
String ss=sb4.toString();
return ss;
//return new StringBuilder(s).reverse().toString();
}
指定位置反转
Scanner sc=new Scanner(System.in);
System.out.println("输入一个字符串");
String str1=sc.nextLine();
System.out.println("输入开始反转的位置");
int start=sc.nextInt();
System.out.println("输入结束反转的位置");
int end=sc.nextInt();
String head = str1.substring(0, start-1);
String tail = str1.substring(end, str1.length()+0);
String mid = str1.substring(start-1, end);
String str2="";
for (int i=mid.length()-1;i>=0;i--){
str2+=mid.charAt(i);
}
String str3=head+str2+tail;
System.out.println(str3);
集合 ArrayList
public ArrayList() 创建空的集合对象
public boolean add(E e) 将指定元素追加到集合末尾 /添加
public void add(int index,E element) 在集合中某位置插入元素 /插入
public boolean remove(Object o)删除指定元素
public E remove(int index )删除指定索引元素 /删除
public E set(int index,E element) 修改指定索引元素 /修改
public E get(int index)返回指定索引元素
public E int size() 返回集合中元素个数
ArrayList<String> array=new ArrayList<String>();
System.out.println(array);
array.add("hello"); //添加 0位置
array.add("world");
System.out.println(array);
array.add(1,"java");//插入
System.out.println(array);
array.remove("world"); //删除
System.out.println(array);
array.remove(1); //删除,不能越界
System.out.println(array);
array.set(0,"hello1"); //修改 不能越界
System.out.println(array);
System.out.println(array.get(0)); //取出元素
System.out.println(array.size()); //计算元素个数
集合遍历
ArrayList<String> array1=new ArrayList<String>();
array1.add("1");
array1.add("2");
array1.add("3");
array1.add("4");
for (int i=0;i< array1.size();i++){
String s=array1.get(i);
System.out.println(s);
}
存储学生对象集合
类文件
public class student3 {
private String name;
private String age1;
public student3(){}
public student3(String name,String age1){
this.name=name;
this.age1=age1;
}
public void setName(String name){
this.name=name;
}
public void setAge1(String age1){
this.age1=age1;
}
public void show(){
System.out.println("姓名:"+name);
System.out.println("年龄:"+age1);
}
对象文件
public static void main(String[] args) {
ArrayList<student3> arr=new ArrayList<student3>();
addstudent(arr);
addstudent(arr);
addstudent(arr);
addstudent(arr);
for (int i=0;i< arr.size();i++){
student3 s6= arr.get(i);
s6.show();
}
}
public static void addstudent(ArrayList<student3> arr){
Scanner sc=new Scanner(System.in);
System.out.println("请输入学生姓名");
String name= sc.nextLine();
System.out.println("请输入学生年龄");
String age=sc.nextLine();
student3 s5=new student3(name,age);
arr.add(s5);
}
继承
public class 子类名 extends 父类名()
public class zi extends fu()
子类 可以有父类的内容 也可以有自己的内容 也可以有父类的父类内容(多层继承)
对象文件可以从子类导入父类文件
父类
public class jcfu {
public void show(){
System.out.println("f");
}
}
子类
public class jczi extends jcfu {
public void show1(){
System.out.println("z");
}
}
对象
public class jcdeom {
public static void main(String[] args) {
jcfu f = new jcfu();
f.show();
jczi z = new jczi();
z.show();
z.show1();
}
}
访问关系
父类
public class jcfu extends jcyy {
public int age = 10;
}
子类
public class jczi extends jcfu {
public int age=20;
public void show(){
int age=30;
//访问本方法的age
System.out.println(age);
//访问本成员变量的age
System.out.println(this.age);
//访问父类成员变量的age
System.out.println(super.age);
}
}
对象
public class jcdeom {
public static void main(String[] args) {
jczi z = new jczi();
z.show();
}
}
访问构造方法特点
子类中所有构造方法默认都会访问父类中无参构造方法super()
如果父类中无无参构造方法 则需要给出super(x);
方法重写
@Override 检测重写的方法是否与父类相同
父类中私有的(private)方法不能被子类重写和继承
子类重写的方法访问权限不能比父类低(public>无>private)
父类
public class phone3 {
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
子类
public class phonenew extends phone3 {
@Override
public void call(String name){
System.out.println("开启视频功能");
super.call(name);
}
}
对象
public class phoneDeom3 {
public static void main(String[] args) {
phone3 p=new phone3();
p.call("莫");
System.out.println("-----------");
phone3 np=new phonenew();
np.call("莫");
}
}
多层继承
人 类
public class person {
private String name;
private int age;
public person() { //无参构造方法
}
public person(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;
}
}
老师类 继承人类 默认可以使用人类中无参构造方法
public class teacher extends person {
private String teach;
public teacher() {
}
public teacher(String name,int age){
super(name,age); //使用父类中有参构造的name age
}
public String getTeach() {
return teach;
}
public void setTeach(String teach) {
this.teach = teach;
}
}
学生类 继承老师类 可以使用老师和人类中所有方法
public class student extends teacher{
private String stduy;
public student() {
}
public student(String name,int age){
super(name,age);
}
public String getStduy() {
return stduy;
}
public void setStduy(String stduy) {
this.stduy = stduy;
}
}
对象
public class studentDeom {
public static void main(String[] args) {
//创建老师类对象
teacher t1 = new teacher();
t1.setName("1,");
t1.setAge(18);
System.out.println(t1.getName()+t1.getAge());
t1.setTeach("教书育人");
System.out.println(t1.getTeach());
//有参构造方法
teacher t2=new teacher("2,",19);
System.out.println(t2.getName()+t2.getAge());
t2.setTeach("教书育人");
System.out.println(t2.getTeach());
//创建学生类对象
student s1=new student();
s1.setName("3,");
s1.setAge(18);
s1.setStduy(",努力学习");
s1.setTeach("教育同学"); System.out.println(s1.getName()+s1.getAge()+s1.getStduy()+s1.getTeach());
}
}
多态
impoet 包名;
package package1;
import studentManager1.student; //导包
public class packageDeom {
student s=new student();
}
权限修饰符
public class jcfu {
public int age = 10;
private void show1(){
System.out.println("private修饰 只能本类中访问");
}
void show2(){
System.out.println("无修饰 本文件中子类或无关系可以访问");
}
public void show3(){
System.out.println("public修饰 其他文件中的子类可以访问");
}
public static void show4(){
System.out.println("static 不同文件的无关的可以访问");
}
}
状态修饰符
final 最终
final修饰变量 则该变量是常量,不能被修改
final修饰方法 该方法不能被重写
final修饰类 则该类不能被继承
final修饰基本类型(值) 则数据值不能在改变
final修饰引用类型(地址) 则地址不能改变 但地址中的值可以改变
static修饰 (静态) 被所有对象共享
static访问
非静态成员方法:
可以访问静态成员变量和非静态成员变量
可以访问静态成员方法和非静态成员方法
静态成员方法:
只能访问静态成员变量和静态成员方法
类
public class student {
public static String university;
public String name;
public int age;
public void show(){
System.out.println(name+age+university);
}
}
对象
public static void main(String[] args) {
student.university="长春大学";
student s1=new student();
s1.name="1";
s1.age=18;
s1.show();
student s2=new student();
s2.name="2";
s2.age=18;
s2.show();
}
多态前提 有继承/实现光系 有方法重写 有父类引用指向子类对象
父类名 名=new 子类名(); animal a=new cat();
变量:编译都看左边
方法:编译看左边 运行看右边 p171
父类
public class animal {
public String name;
public int age;
public void eat(){
System.out.println("动物");
}
}
子类
public class cat extends animal {
public String eat = "猫";
public void eat() {
System.out.println("猫吃鱼");
}
}
对象
public class animalDeom {
public static void main(String[] args) {
//父类引用指向子类对象
animal a=new cat();
a.name("猫");//访问成员变量 是访问父类的成员变量
//System.out.println(a.eat);
System.out.println(a.name);
//访问方法,父类有此方法才能访问,运行结果子类优先
a.eat();
}
}
多态
父类
public class animal {
public void eat(){
System.out.println("动物");
}
}
子类1
public class cat extends animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
子类2
public class dog extends animal {
public void eat(){
System.out.println("狗吃肉");
}
}
中转处
public class op {
// public void useanimal(cat c){ //cat c=new cat();相当于创建了一个cat的对象
// c.eat(); //将eat可以传到cat里 需要方法重写
// }
// public void useanimal(dog d){ //同理
// d.eat();
// }
public void useanimal(animal a){ //animal a=new cat()
a.eat(); //animal d=new dog()
}
}
运行台
public class animalDeom {
public static void main(String[] args) {
op o=new op();
cat c=new cat();
o.useanimal(c); //c=new cat()传到useanimal
dog d=new dog();
o.useanimal(d);//同理
}
}
多态转型
public class animalDeom {
public static void main(String[] args) {
//多态
animal a=new cat();//向上转型 父类引用指向子类对象
a.eat();
// a.paly(); // 父类中没有paly 所以不能使用
cat c=(cat)a; //向下转型 父类引用转为子类对象
c.paly();
}
}
抽象类 abstract
抽象类和抽象方法必须使用abstrct修饰
父类
public abstract class animal { //抽象类 不能直接创建对象
public abstract void eat();
//抽象方法 一定在抽象类里 子类中必须有该方法重写
}
子类
public class cat extends animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
对象
public class animalDeom {
public static void main(String[] args) {
animal a=new cat(); //抽象类需要用多态形式创建对象
a.eat();
}
}
接口用interface(实现)修饰 public interface 名 {}
类实现接口用implements表示 public class 类名 implements 接口名{}
接口中只能有抽象方法
接口中的成员变量只能是常量 被final默认修饰
接口和接口是继承关系,可以多继承
一个类 可以实现多个接口
接口1
public interface jiekou1 {
public abstract void jump();
}
接口2
public interface jiekou2 {
public abstract void eat();
}
类
public class jiekouDeom implements jiekou1,jiekou2 {
public void jump(){
System.out.println("跳高");
}
public void eat(){
System.out.println("吃饭");
}
}
对象
public static void main(String[] args) {
jiekou j=new jiekouDeom(); //有实现关系 有重写
j.jump();
j.eat();
}